Search and Sum based on selection - excel

I tried Sum, CountIf, Dsum, SumProduct
I have a Userform with a ComboBox "History_Select_Debtor". The RowSource for the ComboBox is "Debtor_list_Debtors" - A Dynamic Named Range on WorkSheet "DebtorList". It consists of Customer Names from A2:A24 but will grow eventually.
The UserForm also Has a Textbox for Total Items Purchased Named "txtPurchased".
With each Transaction a Record is saved on Worksheet "InvoiceList" which consists of 7 Columns.
Each of these Columns have Dynamic Named Ranges
A = "Debtor" (Invoice_list_Debtor)
B = "Item" (Invoice_list_Item)
C = "Price" (Invoice_list_Price)
D = "Date" (Invoice_list_Date)
E = "Time" (Invoice_list_Time)
F = "Balance" (Invoice_list_Balance)
G = "Payed" (InvoiceList_Payed)
The Record Saved in the Item Column is Text;
"Payed Balance","Added Balance","Quarter Item","Half Item","1 Item" - "10 Items"
I need to, "Based on the combo selection (History_Select_Debtor)", Reference that Particilar Debtor with "InvoiceList", sum up the total Number of Purchases and display that Value in "txtPurchased".
I need a specific Value to be assigned to each Item e.g. "Quarter Item" = 0.25 or "5 Item = 5".
If as an example "Adrian" has 7 Transactions recorded on InvoiceList
Added Balance
Quarter Item
Half Item
Quarter Item
10 Items
4 Items
Payed Balance
The Value to be displayed in "txtPurchased" would be "15".
I've a Macro that sums up the total Purchases;
It sums up the Total Row rather than just whichever Debtor is Selected in "History_Select_Debtor"
'-------Total Transactions----------------------------------------------------------------------
Set ws = Worksheets("DebtorList")
With Me
'Starting point of lookup data
Rw = .History_Select_Debtor.ListIndex + 2
History_Select_Debtor.List = Range("Debtor_list_Debtors").Value
txtTransactions.Value = Application.CountIf(Range("Invoice_list_Debtor"), History_Select_Debtor)
End With
'-----------------------------------------------------------------------------------------------
Another Macro I've made which also won't work;
=SUM(IF(Invoice_list_Item="Quarter Item",0.25,0)+IF(Invoice_list_Item="Half Item",0.5,0)+IF(Invoice_list_Item="1 Item",1,0)+IF(Invoice_list_Item="2 Items",2,0)+IF(Invoice_list_Item="3 Items",3,0)+IF(Invoice_list_Item="4 Items",4,0)+IF(Invoice_list_Item="5 Items",5,0)+IF(Invoice_list_Item="10 Items",10,0))
The Issue with this one is that given I use the Invoice_list_Debtor as the RowSource for my ComboBox I end up with over 170 duplicate Names.
Here is the Source Code to the Page I need to code to work on;
Public ListTable As Long
Private Sub UserForm_Initialize()
History_Select_Debtor.List = Range("Debtor_list_Debtors").Value
History_Select_Debtor = ""
Label6.Visible = False
Label7.Visible = False
Label8.Visible = False
Label9.Visible = False
Label10.Visible = False
Label11.Visible = False
Label12.Visible = False
Dim ws As Worksheet
Set ws = Worksheets("InvoiceList")
ListTable = ws.Range("A65536").End(xlUp).Row
Me.ListBox1.List = Range("A2:G" & ListTable).Value
Me.ListBox1.Clear
Me.ListBox1.ColumnWidths = "50;80;70;100;80;80;80"
'-----------Listview--------------------------------------------------------------------------------------------------------------
'Dim ws As Worksheet
'Dim lngRow As Long
'Dim lvwItem As ListItem
'Dim lngEndCol As Long
'Dim lngCol As Long
'Dim lngEndRow As Long
'Dim lngItemIndex As Long
'Dim blnHeaders() As Boolean
'Dim Rw As Long
'Set ws = Worksheets("InvoiceList")
'lngEndCol = ws.Range("A1").End(xlToRight).Column
'lngEndRow = ws.Range("A1").End(xlDown).Row
'ListView1.Gridlines = True
'lngRow = 1
'With ListView1
'.View = lvwReport
'For lngCol = 1 To lngEndCol
'.ColumnHeaders.Add , , ws.Cells(lngRow, lngCol).Text, ws.Columns(lngCol).ColumnWidth + 59.6
'.BackColor = vbBlack
'Next
'For lngRow = 2 To lngEndRow
'lngCol = 1
'lngItemIndex = 0
'Set lvwItem = .ListItems.Add(, , (ws.Cells(lngRow, lngCol).Text))
'For lngCol = 2 To lngEndCol
'lngItemIndex = lngItemIndex + 1
'lvwItem.SubItems(lngItemIndex) = Format(ws.Cells(lngRow, lngCol).Text, ws.Cells(lngRow, lngCol).NumberFormat) 'Adds Value from Current Row and Column 1
'Next
'Next
'.TextBackground = lvwTransparent
'End With
'-----------Listview--------------------------------------------------------------------------------------------------------------
'-----------ChartSpace---------------------------------------------------
Dim ChtSpc As OWC11.ChartSpace
Dim cht As OWC11.ChChart
Dim Sps As OWC11.Spreadsheet
Dim owcChart As OWC11.ChartSpace
Dim Balance As String
Balance = Range("B1").Value
Set owcChart = Me.ChartSpace1
Set ChtSpc = Me.ChartSpace1
Set Sps = Me.Spreadsheet1
Set ws = ThisWorkbook.Worksheets("DebtorList") ' change to you worksheet name
Sps.Range("A1:B100") = ws.Range("A1:B100").Value ' Set worksheet range to sheet control range
Set ChtSpc.DataSource = Sps ' set sheet control as chart control source
Set cht = ChtSpc.Charts.Add ' Add blank chart
With cht ' Set data for chart
.SetData chDimCategories, 0, "A2:A25" ' change to your category range
.SeriesCollection(0).SetData chDimValues, 0, "B2:B25" ' change to your series 1 range
'.PlotArea.FlipHorizontal
'.PlotArea.FlipVertical
'.PlotArea.RotateClockwise
'.SeriesCollection.Add
'.SeriesCollection(1).SetData chDimValues, 0, "A1:A24" ' change to your series 2 range
'By changing the layout we can control how the charts are presented
'inside the Chart space.
.Interior.Color = RGB(0, 0, 0)
.Border.Color = vbWhite
.Border.Weight = Thick
'.Type = chChartTypeColumn3D
'.Type = chChartTypeAreaStacked
End With
Me.Spreadsheet1.Visible = False ' hide the sheet control
'Set up the charts and manipulate some of their properties.
With owcChart.Charts(0)
'The data reference must be of the datatype string.
'The last parameter specify if each row represent a serie or not.
'.HasTitle = True
With .PlotArea
.Interior.Color = RGB(0, 0, 0)
'.Border.Color = RGB(255, 255, 255)
'.Border.DashStyle = chLineSolid
'.Border.Weight = Thick
End With
'With .Title
'.Caption = Balance
'.Font.Name = "Verdana"
'.Font.Size = 10
'.Font.Bold = True
'.Font.Color = RGB(50, 205, 50)
'End With
With .Axes(0).Font
.Name = "Verdana"
.Size = 8
'.Bold = True
.Color = RGB(255, 255, 255)
End With
With .Axes(1).Font
.Name = "Verdana"
.Size = 8
'.Bold = True
.Color = RGB(255, 255, 255)
End With
'With .Axes(0).MinorGridlines
'.Line.Color = RGB(255, 255, 255)
'End With
'With .Axes(0).MajorGridlines
'.Line.Color = RGB(255, 255, 255)
'End With
'With .Axes(1).MinorGridlines
'.Line.Color = RGB(255, 255, 255)
'End With
'With .Axes(1).MajorGridlines
'.Line.Color = RGB(255, 255, 255)
'End With
With .SeriesCollection(0)
'.Border.Color = RGB(255, 255, 255)
.Interior.Color = vbGreen
.Caption = Balance
.Line.Color = RGB(255, 255, 255)
End With
'With .SeriesCollection(1)
'.Interior.Color = vbBlue
'.Caption = Balance
'End With
'.HasLegend = True
'With .Legend
'.Position = chLegendPositionBottom
'.Border.Color = vbWhite
'.LegendEntries(2).Visible = False
'End With
End With
'------------------------------------------------------------------------
End Sub
Private Sub cmdClose_History_Click()
Unload Me
frmMenu.Show
End Sub
Private Sub History_Select_Debtor_Change()
'--------Total Purchased-----------------------------------------------
'Worksheets("InvoiceList").Rows(1).AutoFilter Field:=1, Criteria1:="=" & Me.History_Select_Debtor
'Me.txtPurchased = Worksheets("Summary").[C2] 'the cell containing the SUBTOTAL
'-------------------------------------------------------
Label6.Visible = True
Label7.Visible = True
Label8.Visible = True
Label9.Visible = True
Label10.Visible = True
Label11.Visible = True
Label12.Visible = True
FilterList 0, Me.History_Select_Debtor.Text
Me.cmdClose_History.SetFocus
Dim ws As Worksheet
Dim Rw As Long
Set ws = Worksheets("DebtorList")
'Get row based on ComboBox ListIndex
With Me
'Starting point of lookup data
Rw = .History_Select_Debtor.ListIndex + 2
'Data to be displayed based on selection
txtBalance.Value = FormatCurrency(Expression:=ws.Cells(Rw, 2).Value, _
NumDigitsAfterDecimal:=2)
End With
'-------Total Transactions----------------------------------------------------------------------------------------------------------------------
Set ws = Worksheets("DebtorList")
With Me
'Starting point of lookup data
Rw = .History_Select_Debtor.ListIndex + 2
History_Select_Debtor.List = Range("Debtor_list_Debtors").Value
txtTransactions.Value = Application.CountIf(Range("Invoice_list_Debtor"), History_Select_Debtor)
End With
'-------Total Payed------------------------------------------------------------------------------------------------------------------------------
txtPayed.Value = FormatCurrency(Expression:=Application.SumIf(Range("Invoice_list_Debtor"), _
History_Select_Debtor.Value, Range("Invoice_list_Price")), _
NumDigitsAfterDecimal:=2)
End Sub
Private Sub UserForm_QueryClose _
(Cancel As Integer, CloseMode As Integer)
' Prevents use of the Close button
If CloseMode = vbFormControlMenu Then
Cancel = True
End If
End Sub
Private Sub FilterList(iCtrl As Long, sText As String)
Dim iRow As Long
Dim ws As Worksheet
Dim sCrit As String
sCrit = "*" & UCase(sText) & "*"
Set ws = Worksheets("InvoiceList")
With Me.ListBox1
ListTable = ws.Range("A65536").End(xlUp).Row
.List = ws.Range("A2:G" & ListTable).Value
For iRow = .ListCount - 1 To 0 Step -1
If Not UCase(.List(iRow, iCtrl)) Like sCrit Then
.RemoveItem iRow
End If
Next iRow
'Determine number of columns
.ColumnCount = 7
'Set column widths
.ColumnWidths = "50;80;70;100;80;80;80"
'Insert the range of data supplied
For x = 2 To 3 'loop the numeric columns - 3 to 4
For i = 0 To .ListCount - 1 'loop through the rows of columns 3 to 5
.List(i, x) = Format(.List(i, x), "$#,##")
Next i
Next x
For x = 5 To 6 'loop the numeric columns - 4 to 5
For i = 0 To .ListCount - 1 'loop through the rows of columns 3 to 5
.List(i, x) = Format(.List(i, x), "$#,##")
Next i
Next x
For x = 4 To 4 'loop the numeric columns - 3 to 4
For i = 0 To .ListCount - 1 'loop through the rows of columns 3 to 5
.List(i, x) = Format(.List(i, x), "[$-409]h:mm AM/PM;#")
Next i
Next x
End With
End Sub

There is more than one issue here I believe ...
To get the total number of invoiced items for a debtor you can
(auto)filter the InvoiceList for your current Debtor
display the sum of invoiced items using the =SUBTOTAL(109,InvoiceSheet!$F:$F) worksheet function (asuming the invoice sheet is named [InvoiceSheet] ;-) )
I would even suggest to have that =SUBTOTAL on a seperate sheet (Sheet2), so it's location is constant. Don't use ControlSource() on the text field in the dialog, but set Locked = True
You can set up Autofilter on [InvoiceSheet] once and use the Sub
Private Sub History_Select_Debtor_Change()
Worksheets("InvoiceSheet").Rows(1).AutoFilter field:=1, Criteria1:="=" & Me.History_Select_Debtor
Me.txtPurchased = Worksheets("Sheet2").[A1] 'the cell containing the SUBTOTAL
End Sub
to fire the filter and get the value of the SUBTOTAL formula back into the dialog.
For the transition of quantities from text to number I would suggest to create an extra sheet [QTYCode] looking like
A B ...
+------------+-----+----
1 |Text |Value|
2 |Quarter item| 0.25|
3 |Half item | 0.5|
4 |1 item | 1|
5 |2 item | 2|
6 |3 item | 3|
...
where column A (except header row) serves as RowSource() for the QTY selection box, and for each record you create in [InvoiceSheet] you save not only the selected QTYText, but as well an extra column containing a =VLOOKUP() formula that converts text into value (and base your =SUBTOTAL() on that new column - of course)
Hope that helps
Good luck - MikeD

Related

Need help converting macro from horizontal to vertical coloring

I need some help transforming an existing code to color cells based on a value horizontally to vertically.
I've been trying all kinds of things but I can't figure out on how to edit the code to work vertically. The first picture is the existing horizontal coloring which works great, the second picture is how I need to coloring to be done.
Anyone who can help me in the right direction? I do have a testfile that I can share with all the sheets.
The code basically gets the colors and location out of different sheets but this is working / ok.
The 3th pictures is a screenshot of the ranges tab with how the ranges are set up for the query.
Existing Plan:
New Plan:
Ranges Tab:
My code:
'Sheet renamers
Dim wb As Workbook
Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = wb.Worksheets("Plan")
Dim queryws As Worksheet
Set queryws = wb.Worksheets("Query")
queryws.AutoFilterMode = False
Dim colorws As Worksheet
Set colorws = wb.Worksheets("Colors")
colorws.AutoFilterMode = False
Dim rangews As Worksheet
Set rangews = wb.Worksheets("Ranges")
rangews.AutoFilterMode = False
lr = rangews.Range("A1000").End(xlUp).Row
'Remove colors from each block
For i = 2 To lr
LocAddress = rangews.Range("D" & i).Value
ws.Range(LocAddress).Interior.Color = 16777215
Next i
'Run through query
lrquery = queryws.Range("A100000").End(xlUp).Row
queryws.UsedRange.AutoFilter Field:=40, Criteria1:="Location"
For Each c In queryws.UsedRange.Offset(1, 0).Resize(lrquery - 1).Columns(11).SpecialCells(xlCellTypeVisible).Cells
blok = Left(c.Value, 3)
CombinedAddress = Application.WorksheetFunction.VLookup(blok, rangews.Range("A:E"), 5, False)
BeginRow = Application.WorksheetFunction.VLookup(blok, rangews.Range("A:G"), 6, False)
EndRow = Application.WorksheetFunction.VLookup(blok, rangews.Range("A:G"), 7, False)
BeginColumn = Application.WorksheetFunction.VLookup(blok, rangews.Range("A:H"), 8, False)
Disc1 = c.Offset(0, -10).Value
If Disc1 <> "" Then
On Error Resume Next
kleur = 0
kleur = Application.WorksheetFunction.VLookup(Disc1, colorws.Range("A:C"), 3, False)
If kleur = 0 Then
MsgBox ("Please add " & Disc1)
Exit Sub
End If
On Error GoTo 0
Else
kleur = 65535
End If
Set R1 = ws.Range(CombinedAddress)
Sublocation = Right(c.Value, 2)
kolominrange = Application.WorksheetFunction.Match(CLng(Sublocation), R1)
kolominws = BeginColumn + kolominrange - 1
'Coloring
For Each c3 In ws.Range(ws.Cells(BeginRow, kolominws), ws.Cells(EndRow, kolominws))
If c3.Interior.Color = 16777215 And c3.MergeCells = False Then
c3.Interior.Color = kleur
c.Interior.Color = kleur
Exit For
End If
Next c3
Next c

Inserting entries on new sheet based on a data sheet

From our drawing program we receive a sheet with data for sawing sheet material. We want to make a sticker for each unique plate.
The idea is, rearrange the data into a sticker format on a new sheet.
jpeg image for example.
Sub Platen_stickers()
Application.ScreenUpdating = False
Dim i As Long
Dim j As Long
Dim xLast As Long
Dim rw As Range
Dim aantalrng As Range
Dim aantal As Range
Dim plaattype As Range
Dim Merk As String, Label As String, Lengte As String, Breedte As String
Dim stickeraantal As Byte, stickergemaakt As Byte
Dim sticker As Range
Dim row As Range
Dim x As Long
On Error Resume Next
xLast = ActiveWorkbook.Sheets(1).Cells(Rows.Count, "B").End(xlUp).row 'searching last filled cell in column B
For i = 8 To xLast Step 1
If Sheets(1).Cells(i, "B").Value2 = "Code" Then 'searching for header "Code" in column B
Set plaattype = Sheets(1).Cells(i + 1, "B") 'defining the cell below "Code" as range "plaattype"
Set aantal = plaattype.Offset(0, 2) 'defining cell in row below "Code" and in column D as range "aantal"
Set aantalrng = Range(aantal, aantal.End(xlDown)) 'defining all numbers in column D under this header as range "aantalrng"
'inserting new sheet for stickers after current last sheet
ActiveWorkbook.Sheets.Add After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Name = plaattype.Value2 'editing sheet name to current type
Set sticker = ActiveSheet.Range(1, 1) 'defining cell A1 of current sheet as current sticker
With ActiveSheet.Range("A1:F31") 'adjusting cell dimensions of range A1:F32 to sticker format (96 sticker per sheet)
.Columns("A:F").ColumnWidth = 18.14
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
For Each rw In ActiveSheet.Range("A1:F32").Rows
If rw.row Mod 2 = 0 Then
rw.RowHeight = 5.25
Else: rw.RowHeight = 53.25
End If
Next rw
With ActiveSheet.PageSetup 'adjusting print settings to fit stickersheet
.CenterHorizontally = True
.CenterVertically = True
.LeftMargin = Application.CentimetersToPoints(0)
.RightMargin = Application.CentimetersToPoints(0)
.TopMargin = Application.CentimetersToPoints(0.6)
.BottomMargin = Application.CentimetersToPoints(0.6)
.HeaderMargin = Application.CentimetersToPoints(1.3)
.FooterMargin = Application.CentimetersToPoints(1.3)
.Zoom = 87
End With
x = 1 'setting sticker count on 1
'creating the actual sticker
For Each row In aantalrng 'running through current data for creating stickers
stickergemaakt = 0 'resetting counter made sticker in this row
stickeraantal = aantalrng.Cells(row, 1).Value 'checking how many stickers this row needs making (=value of column D)
Do Until stickergemaakt > stickeraantal 'looping until made stickers is needed stickers
Merk = aantalrng.Cells(row, 1).Offset(0, -1).Value 'collecting sticker input
Label = aantalrng.Cells(row, 1).Offset(0, -3).Value
Lengte = aantalrng.Cells(row, 1).Offset(0, 1).Value
Breedte = aantalrng.Cells(row, 1).Offset(0, 2).Value
sticker.Value = Merk & " " & Label & vbCrLf & Lengte & " x " & Breedte & " mm" & vbCrLf & plaattype 'writing sticker input in format on current cell on sticker sheet
If x < 6 Then
Set sticker = sticker.Offset(0, 1) 'adjusting to new empty sticker cell => next column
x = x + 1
ElseIf x = 6 Then
sticker = sticker.Offset(1, -6) 'until reached 6 columns, then next row to start again
x = 1
End If
stickergemaakt = stickergemaakt + 1 'adding counter made sticker with 1
Loop
stickeraantal = 0 'resetting number of stickers needed to zero for next row
Next row
End If
Next
Application.ScreenUpdating = True
End Sub
The first part, inserting extra sheets and adjusting to the sticker sizes, works in my sample file.
The second part, filling the stickers with the data, I can't get started.
I suspect I'm doing something wrong with declaring the range per header.
But whatever I adjust in it, the second part doesn't work and sometimes the first part doesn't either.

VBA Macro : Compare / check 3 sheets and return differences value

I have 3 sheets that need to check if they have same value. All value on column B6 until last row should be same in Sheets MM, PP and CO. If there's difference value, the different value should be on highlight (the color is red).
But, my syntax didn't run. The syntax just can read if there's an empty column in range. This is my syntax.. Not including highlight. First, i tried to place the difference value to the other sheets. But, failed. Thank you.
Sub MatchValue()
Dim x As Integer
Dim y As Integer
Dim z As Integer
LastRowB = Cells(Rows.Count, "B").End(xlUp).Row
x = ActiveWorkbook.Worksheets("MM").Range("B6:B" & LastRowB).Cells.SpecialCells(xlCellTypeConstants).Count
y = ActiveWorkbook.Worksheets("PP").Range("B6:B" & LastRowB).Cells.SpecialCells(xlCellTypeConstants).Count
z = ActiveWorkbook.Worksheets("CO").Range("B6:B" & LastRowB).Cells.SpecialCells(xlCellTypeConstants).Count
If x <> y Then
MsgBox "MM <> PP", vbCritical, "Error Report"
End If
If y <> z Then
MsgBox "PP <> CO", vbCritical, "Error Report"
End If
If z <> x Then
MsgBox "CO <> MM", vbCritical, "Error Report"
End If
SheetMM = "MM"
DataColumnMM = "B6"
SheetPP = "PP"
DataColumnPP = "B6"
SheetCO = "CO"
DataColumnCO = "B6"
SheetUnmatched = "Data Unmatched"
DataColumnUnmatched = "A1"
DataRowMM = Range(DataColumnMM).Row
DataColMM = Range(DataColumnMM).Column
DataRowPP = Range(DataColumnPP).Row
DataColPP = Range(DataColumnPP).Column
DataRowCo = Range(DataColumnCO).Row
DataColCo = Range(DataColumnCO).Column
DataRowUnmatched = Range(DataColumnUnmatched).Row
DataColUnmatched = Range(DataColumnUnmatched).Column
LastDataMM = Sheets(SheetMM).Cells(Rows.Count, DataColMM).End(xlUp).Row
LastDataPP = Sheets(SheetPP).Cells(Rows.Count, DataColPP).End(xlUp).Row
LastDataCO = Sheets(SheetCO).Cells(Rows.Count, DataColCo).End(xlUp).Row
LastDataUnmathced = Sheets(SheetUnmatched).Cells(Rows.Count, DataColUnmatched).End(xlUp).Row
For counter = DataRowMM To LastDataRowMM
If WorksheetFunction.CountIf(LastDataPP, counter) = 0 Then
LastDataUnmathced.Offset(1) = counter
End If
Next
For counter = DataRowMM To LastDataRowMM
If WorksheetFunction.CountIf(LastDataCO, counter) = 0 Then
LastDataUnmathced.Offset(1) = counter
End If
Next
For counter = DataRowPP To LastDataRowPP
If WorksheetFunction.CountIf(LastDataCO, counter) = 0 Then
LastDataUnmathced.Offset(1) = counter
End If
Next
End Sub
Based on the information you've provided, you want to:
Check three tables across three sheets in the ActiveWorkbook
Check to see if the same number of constants exists in the table ranges
Highlight cells red where the values between the three sheets aren't the same
I've simplified the code in order to achieve these targets
Sub MatchValue()
Dim Range1 As Range, Range2 As Range, Range3 As Range
With ActiveWorkbook
With .Sheets("MM") 'First Sheet Name
Set Range1 = .Range("B6") 'Address of first row on First Sheet
Set Range1 = .Range(Range1, .Cells(.Rows.Count, Range1.Column).End(xlUp))
End With
With .Sheets("PP") 'Second Sheet Name
Set Range2 = .Range("B6") 'Address of first row on second Sheet
Set Range2 = .Range(Range2, .Cells(.Rows.Count, Range2.Column).End(xlUp))
End With
With .Sheets("CO") 'Third Sheet Name
Set Range3 = .Range("B6") 'Address of first row on third Sheet
Set Range3 = .Range(Range3, .Cells(.Rows.Count, Range3.Column).End(xlUp))
End With
End With
'Delete this part if you don't want to remove the existing fill (might be handy)
Range1.Interior.Pattern = xlNone
Range2.Interior.Pattern = xlNone
Range3.Interior.Pattern = xlNone
'Checks to see if the same number of constants exist within the test ranges
If Range1.SpecialCells(xlCellTypeConstants).Count <> _
Range2.SpecialCells(xlCellTypeConstants).Count Then
MsgBox "Range 1 and Range 2 constant count doesn't match", vbCritical, "Error Report"
ElseIf Range2.SpecialCells(xlCellTypeConstants).Count <> _
Range3.SpecialCells(xlCellTypeConstants).Count Then
MsgBox "Range 1 and Range 2 constant count doesn't match", vbCritical, "Error Report"
End If
Dim Temp1 As Variant, Temp2 As Variant, Temp3 As Variant, x As Long
'Checks to see if all the values entered are the same, if not, fills them red
Temp1 = Range1.Value
Temp2 = Range2.Value
Temp3 = Range3.Value
For x = 1 To UBound(Temp1, 1)
If Temp1(x, 1) <> Temp2(x, 1) Or _
Temp2(x, 1) <> Temp3(x, 1) Then
Range1.Cells(x, 1).Interior.Color = RGB(255, 0, 0)
Range2.Cells(x, 1).Interior.Color = RGB(255, 0, 0)
Range3.Cells(x, 1).Interior.Color = RGB(255, 0, 0)
End If
Next x
End Sub

How to extract values of multiple listboxes on Excel sheet?

I have a userform with multiple checkboxes and listboxes, where each checkbox controls the values of one listbox each.
After clicking on 'Next' the userform inputs the selected values of each listbox on the Excel sheet. I am able to achieve this only for one pair of checkbox and listbox at a time. But I want the results of each shortlisted items one after the other.
Private Sub cmdFDB_Next_Click()
Dim ColCount As Integer, lastrow As Integer
Dim lastrow1 As Integer
Dim Data As Integer
Dim i As Integer
lastrow = Worksheets("Model Portfolio").Cells(Rows.Count, 2).End(xlUp).Row
With Worksheets("Model Portfolio").Cells(lastrow, 2)
.Offset(2, 0).Value = "Fixed Deposits and Bonds"
.Offset(2, 0).Font.Bold = True
.Offset(2, 0).Font.Size = 12
For i = 2 To lastrow
If Me.chkGB.Value = True Then
.Offset(3, 0).Value = "Government Bonds"
.Offset(3, 0).Font.Bold = True
.Offset(3, 2).Value = Format(Me.txtGB.Value, "Currency")
lastrow1 = lastrow + 4
ColCount = 2
With Me.lbxGB
'loop through each listbox item to see if they are selected
For Data = 0 To .ListCount - 1
If .Selected(Data) = True Then
Cells(lastrow1, ColCount).Value = .List(Data)
lastrow1 = lastrow1 + 1
End If
Next Data
End With
End If
If Me.chkCFD.Value = True Then
.Offset(3, 0).Value = "Corporate Fixed Deposits"
.Offset(3, 0).Font.Bold = True
.Offset(3, 2).Value = Format(Me.txtCFD.Value, "Currency")
lastrow1 = lastrow + 4
ColCount = 2
With Me.lbxCFD
'loop through each listbox item to see if they are selected
For Data = 0 To .ListCount - 1
If .Selected(Data) = True Then
Cells(lastrow1, ColCount).Value = .List(Data)
lastrow1 = lastrow1 + 1
End If
Next Data
End With
End If
If Me.chkTSB.Value = True Then
.Offset(3, 0).Value = "Tax Saving Bonds"
.Offset(3, 0).Font.Bold = True
.Offset(3, 2).Value = Format(Me.txtTSB.Value, "Currency")
lastrow1 = lastrow + 4
ColCount = 2
With Me.lbxTSB
'loop through each listbox item to see if they are selected
For Data = 0 To .ListCount - 1
If .Selected(Data) = True Then
Cells(lastrow1, ColCount).Value = .List(Data)
lastrow1 = lastrow1 + 1
End If
Next Data
End With
End If
Next i
End With
With MultiPage1
.Value = (.Value + 1) Mod (.Pages.Count)
End With
End Sub
Extract selected listbox items to sheet
As you aren't consequent in your row numbering (never changing lastrow mixed with additional offsets and increments), you are loosing track of the actual row numbers.
It's also better practice to use a Sub procedure (here: WriteItems) for repetitive calls and to redefine your lastrow (here: start row) each time. Furthermore I demonstrate how to extract a whole listbox "row" using the Application.Index() function.
Further hint: Instead of direct formatting, consider to use conditional formatting (CF) as you needn't clear old formats in deleted cells (sure you find a lot of examples at SO :-)
BTW I'd prefer to avoid control names containing an underscore "_" as this has some relevance in class implementations.
Main event
Private Sub cmdFDB_Next_Click()
'[0] Define data sheet
Const SHEETNAME As String = "Model Portfolio"
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(SHEETNAME)
'[1] Define abbreviations to identify securities controls
Dim Abbreviations, abbr
Abbreviations = Array("", "GB", "CFD", "TSB") ' first item is EMPTY!
'[2] write data for each security type
Dim OKAY As Boolean
For Each abbr In Abbreviations
'[2a] check
If abbr = vbNullString Then ' Main Title
OKAY = True
ElseIf Me.Controls("chk" & abbr) Then ' individual security checked
OKAY = True
Else
OKAY = False
End If
'==================================
'[2b] write selected data in blocks
'----------------------------------
If OKAY Then WriteItems abbr, ws ' call sub procedure
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Next
End Sub
Sub procedure WriteItems
Private Sub WriteItems(ByVal abbrev As String, ws As Worksheet)
'Purpose: write caption and selected listbox items to sheet
'Note: called by cmdFDB_Next_Click()
Const EMPTYROWS As Long = 1 ' << change to needed space
Const LBXPREFIX As String = "lbx" ' << change to individual checkbox prefix
Const TITLE As String = "Fixed Deposits and Bonds"
With ws
'[0] Define new startrow
Dim StartRow As Long
StartRow = .Cells(Rows.Count, 2).End(xlUp).Row + EMPTYROWS + 1
'[1] Write caption
ws.Cells(StartRow, 2) = getTitle(abbrev) ' function call, see below
If abbrev = vbNullString Then Exit Sub ' 1st array term writes main caption only
'other stuff (e.g. formatting of title above)
'...
'[2] Write data to worksheet
With Me.Controls(LBXPREFIX & abbrev)
Dim i As Long, ii As Long, temp As Variant
For i = 1 To .ListCount
If .Selected(i - 1) = True Then
ii = ii + 1
ws.Cells(StartRow + ii, .ColumnCount).Resize(1, 2).Value = Application.Index(.List, i, 0)
End If
Next i
End With
End With
End Sub
Further note: The Application.Index function allows to get a whole listbox "row" by passing zero (..,0) as second function argument.
Helper function GetTitle()
Function getTitle(ByVal abbrev As String) As String
'Purpose: return full name/caption of security abbreviation
Select Case UCase(abbrev)
Case vbNullString
getTitle = "Fixed Deposits and Bonds"
Case "GB": getTitle = "Government Bonds"
Case "CFD": getTitle = "Corporate Fixed Deposits"
Case "TSB": getTitle = "Tax Saving Bonds"
Case Else: getTitle = "All Other"
End Select
End Function

Referencing an Active-x control with variable in a loop

I'm trying to create a variable for Check boxes in my worksheet so that I can refence a larger number of those in loop.
It looks like this:
The worksheet
The purpose is to make the schedule (Blue background) able to highlight the names you select with the checkboxes (On the left in the green list).
To do this I would like the loop to go through all of those checkboxes and see if they're true for the corresponding name on the same row. I've gotten this far:
Sub Test_ReplaceWithArray()
'State var
Dim Names(54) As String
Dim ChkBx As String
Dim Personal As Range
Dim n, m, i, j, ChkNr, numOfEmployees, numOfWeeks As Integer
'Set var
Set Personal = Range("A3:A55")
numOfEmployees = Application.WorksheetFunction.CountA(Personal)
numOfWeeks = Worksheets("Schemaläggning").numOfWeeksBox.Value
n = 1
m = 3
i = 3
j = 3
ChkNr = 1
ChkBx = ("CheckBox" & ChkNr)
'Fill array
Do Until n > numOfEmployees
Cells(i, 1).Select
If IsEmpty(ActiveCell) = False _
And ChkBx = True Then
Names(n) = ActiveCell.Value
i = i + 1
n = n + 1
ChkNr = ChkNr + 1
ElseIf IsEmpty(ActiveCell) = True Then
i = i + 1
n = n + 1
ChkNr = ChkNr + 1
End If
Loop
'Make Bold or Grey if in array
Do Until m > numOfWeeks + 2
Cells(m, j).Select
If j <= 7 And IsInArray(ActiveCell.Value, Names) = True Then
Selection.Font.Bold = True
j = j + 1
ElseIf j <= 7 And IsInArray(ActiveCell.Value, Names) = False Then
With Selection.Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.349986266670736
End With
j = j + 1
ElseIf j = 8 Then
j = 3
m = m + 1
End If
Loop
End Sub
The point is to have the name on the row (In the green list) put into an array and then look at each name in the schedule. If the name in the cell of the schedule is contained within the array the name will be boldened but if it is'nt it will be turned grey. I have allready made a comparison function to see if the names are contained in the array that works (tested it before continuing with the checkbox references).
But I get runtime error 13 at:
If IsEmpty(ActiveCell) = False _
And ChkBx = True Then
I definatly suspect that I don't know how to reference the control properly but I don't know what to do. Any help is appreciated.
Dim cCont As Control
For Each cCont In Me.Controls
If TypeName(cCont) = "CheckBox" Then
cCont.Value = False
End If
Next cCont
This is a sample of what I use to loop through all controls in a userform. Hopefully you can adjust it to your needs.
for worksheets objects:
Sub LoopListBoxes()
Dim OleObj As OLEObject
For Each OleObj In ActiveSheet.OLEObjects
If OleObj.progID = "Forms.ListBox.1" Then
MsgBox OleObj.Object.ListCount
End If
Next OleObj
End Sub
CheckBox = Forms.CheckBox.1
ComboBox = Forms.ComboBox.1
CommandButton = Forms.CommandButton.1
Frame = Forms.Frame.1
Image = Forms.Image.1
Label = Forms.Label.1
ListBox = Forms.ListBox.1
MultiPage = Forms.MultiPage.1
OptionButton = Forms.OptionButton.1
ScrollBar = Forms.ScrollBar.1
SpinButton = Forms.SpinButton.1
TabStrip = Forms.TabStrip.1
TextBox = Forms.TextBox.1
ToggleButton = Forms.ToggleButton.1
borrowed from:
http://www.ozgrid.com/forum/showthread.php?t=61068

Resources