If I have a listview that is populated, how would I go about changing the font colour if the sub item already exists in that column?
Any help would be appreciated.
This is what I have, but it doesn't work correctly
Sub dupeInterpreters(lvw As ListView, iSubItemIndex As Integer)
Dim i As Integer
Dim dupeI As Integer
dupeI = 0
For i = 1 To LVIV.ListItems.Count
If LVIV.ListItems(i).SubItems(iSubItemIndex) = LVIV.ListItems(i).ListSubItems(iSubItemIndex).Text Then 'you could also use the LIKE operator
'LVIV.ListItems(i).Selected = True
LVIV.ListItems(i).Bold = True
LVIV.ListItems(i).ListSubItems(iSubItemIndex).ForeColor = &HC000&
dupeI = dupeI + 1
'Exit For
End If
Next
End Sub
No error, but it highlights every item in the listview, rather than just the duplicate values
Try the following macro, which formats all duplicates...
Sub dupeInterpreters(LVIV As ListView, iSubItemIndex As Integer)
Dim i As Long
Dim j As Long
Dim bDuplicate As Boolean
bDuplicate = False
For i = 1 To LVIV.ListItems.Count - 1
For j = i + 1 To LVIV.ListItems.Count
If LVIV.ListItems(j).SubItems(iSubItemIndex) = LVIV.ListItems(i).ListSubItems(iSubItemIndex).Text Then
'LVIV.ListItems(i).Selected = True
LVIV.ListItems(j).Bold = True
LVIV.ListItems(j).ListSubItems(iSubItemIndex).ForeColor = &HC000&
bDuplicate = True
End If
Next j
If bDuplicate Then
With LVIV.ListItems(i)
.Bold = True
.ListSubItems(iSubItemIndex).ForeColor = &HC000&
End With
bDuplicate = False
End If
Next
Me.Repaint
End Sub
Hope this helps!
Here's another approach. This one uses the Dictionary object to avoid excessive looping, and should be more efficient...
Sub dupeInterpreters(LVIV As ListView, iSubItemIndex As Integer)
Dim dicListSubItemCount As Object
Dim strListSubItem As String
Dim listItemIndex As Long
Set dicListSubItemCount = CreateObject("Scripting.Dictionary")
dicListSubItemCount.comparemode = 1 'case-insensitive comparison
With LVIV
For listItemIndex = 1 To .ListItems.Count
strListSubItem = .ListItems(listItemIndex).ListSubItems(iSubItemIndex).Text
dicListSubItemCount(strListSubItem) = dicListSubItemCount(strListSubItem) + 1
Next listItemIndex
For listItemIndex = 1 To .ListItems.Count
strListSubItem = .ListItems(listItemIndex).ListSubItems(iSubItemIndex).Text
If dicListSubItemCount(strListSubItem) > 1 Then
With .ListItems(listItemIndex)
.Bold = True
.ListSubItems(iSubItemIndex).ForeColor = &HC000&
End With
End If
Next listItemIndex
End With
Me.Repaint
Set dicListSubItemCount = Nothing
End Sub
Hope this helps!
Related
I have a column in a table that will contain entire phrases with difficult words ("hypothetical exemplification of those akiophrastic words"). I have a list of most words that I expect will be used there.
I found a great solution here but it doesn't quite match my usecase. It works if you want to choose the content of your cell from a list of choices. I want to be able to get suggestions for the currently-typed word within the cell. So I write "hypoth" and click "hypothetical" from the dropdown, then I hit spacebar and start writing "exem" and want to get suggestions for that as well, and so on.
I will try changing the VBA code provided in my hyperlink above but I'm not sure I'll be successful. I'm open to any suggestion. It can also involve userforms although I doubt there is a way using them.
EDIT: On request, I'm summarizing the linked tutorial and posting its code.
It makes you create a Combo Box from the developer tools tab and name it TempCombo.
In the code for the worksheet, where the box is located, you write the following code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Update by Extendoffice: 2020/01/16
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim xArr
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("TempCombo")
With xCombox
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
If Target.Validation.Type = 3 Then
Target.Validation.InCellDropdown = False
Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
If .ListFillRange = "" Then
xArr = Split(xStr, ",")
Me.TempCombo.List = xArr
End If
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.TempCombo.DropDown
End If
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 9
Application.ActiveCell.Offset(0, 1).Activate
Case 13
Application.ActiveCell.Offset(1, 0).Activate
End Select
End Sub
Here's a very basic example using a text box (txt1) and a listbox (lstMatches) on a worksheet:
Option Explicit
Dim suspend As Boolean
Private Sub lstMatches_Click()
Dim word, pos As Long
word = Me.lstMatches.Value
suspend = True
'try to replace the last "word" (or part of word) with the selected word
pos = InStrRev(Me.txt1.Text, " ")
If pos > 0 Then
Me.txt1.Text = Left(Me.txt1.Text, pos) & " " & word
Else
Me.txt1.Text = word
End If
Me.txt1.Activate
suspend = False
End Sub
Private Sub txt1_Change()
Dim txt As String, arr, last As String, allWords, r As Long
If suspend Then Exit Sub 'don't respond to programmatic changes
txt = Trim(Me.txt1.Text)
If Len(txt) = 0 Then 'is there any text?
Me.lstMatches.Clear
Exit Sub
End If
arr = Split(txt, " ")
last = arr(UBound(arr)) 'get the last word
If Len(last) > 1 Then
allWords = Me.Range("words").Value 'get the words list
Me.lstMatches.Clear
For r = 1 To UBound(allWords)
If allWords(r, 1) Like last & "*" Then 'match on "starts with"
Me.lstMatches.AddItem allWords(r, 1)
End If
Next r
End If
End Sub
Using the linked code from my OP and Tim Williams's excellent code, this is the result I got to. To use this, you will have to adapt some lines. There were some really odd bugs which I fixed by adapting some parts. Also added control functionality with Return (+Shift), up and down keys.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim xText As OLEObject
Dim xStr As String
Dim xList As OLEObject
Dim xWs As Worksheet
Dim xArr
Dim ListTarget As Range
' Suggestion box placement
Set ListTarget = Target.Offset(2, 1)
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xText = xWs.OLEObjects("txt1")
Set xList = xWs.OLEObjects("lstMatches")
' Every click lets the boxes disappear.
With xText
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
With xList
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
' Restrict where you want this functionality in your sheet here
If Target.Validation.Type = 3 And Target.column = 10 And Target.row > 4 Then
Target.Validation.InCellDropdown = False
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xText
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 200 ' Size of text box
.Height = Target.Height + 5 ' Make it a little taller for better readability
.ListFillRange = ""
'If .ListFillRange = "" Then
'xArr = Split(xStr, ",")
'Me.TempCombo.list = xArr
'End If
.LinkedCell = Target.Address
End With
With xList
.Visible = True
.Left = ListTarget.Left
.Top = ListTarget.Top
.Width = ListTarget.Width + 200 ' Size of suggestions box
.Height = ListTarget.Height + 100
If .ListFillRange = "" Then 'This loop fills the suggestions with the list from the validation formula, unless already changed by input
xArr = Split(xStr, ",")
xList.ListFillRange = xArr
End If
End With
xText.Activate
Me.lstMatches.Locked = False ' It randomly locked for me, just in case.
' The following two lines fix an obscure bug that made the suggestions un-clickable at random.
ActiveWindow.SmallScroll ToLeft:=1
ActiveWindow.SmallScroll ToRight:=1
End If
End Sub
Private Sub lstMatches_Click()
Dim word, pos As Long
word = Me.lstMatches.value
suspend = True ' disables the text change function for programmatic changes
'try to replace the last "word" (or part of word) with the selected word
pos = InStrRev(Me.txt1.text, " ")
If pos > 0 Then
Me.txt1.text = Left(Me.txt1.text, pos) & word
Else
Me.txt1.text = word
End If
Me.txt1.Activate
suspend = False
End Sub
Private Sub txt1_Change()
Dim txt As String, arr, last As String, allWords, r As Long
Dim data_lastRow As Long
data_lastRow = Worksheets("my_data").Cells(2, 5).End(xlDown).row
If suspend Then Exit Sub 'don't respond to programmatic changes
txt = Trim(Me.txt1.text)
If Len(txt) = 0 Then
Me.lstMatches.Clear
Exit Sub
End If
arr = Split(txt, " ")
last = arr(UBound(arr))
If Len(last) > 1 Then
allWords = Worksheets("my_data").Range("E2:E" & CStr(data_lastRow)).value 'get the words list
Me.lstMatches.Clear
For r = 1 To UBound(allWords)
If allWords(r, 1) Like last & "*" Then 'match on "starts with"
Me.lstMatches.AddItem allWords(r, 1)
If Me.lstMatches.ListCount = 15 Then Exit Sub ' limiting it to 15 suggestions
End If
Next r
End If
End Sub
Private Sub txt1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 13
If Shift = 0 Then
Application.ActiveCell.Offset(1, 0).Activate
Else
Application.ActiveCell.Offset(-1, 0).Activate
End If
Case vbKeyDown
Application.ActiveCell.Offset(1, 0).Activate
Case vbKeyUp
Application.ActiveCell.Offset(-1, 0).Activate
Case vbKeyLeft
Application.ActiveCell.Offset(0, -1).Activate
End Select
End Sub
i need to sort my values by their int values for example
1
2
3
10
1000
but my code works like string like this
1
10
100
2
3
here is my sorting code for EXCEL VBA :
Private Sub lstview1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
With lstview1
.SortKey = ColumnHeader.Index - 1
If .SortOrder = lvwAscending Then
.SortOrder = lvwDescending
Else
.SortOrder = lvwAscending
End If
.Sorted = True
End With
End Sub
how can i fix this for excel vba
The Listview sorts alphabetically and that is one of it's limitations. Here is a quick example that I created for you to sort numeric data.
Code
Option Explicit
Dim i As Long
Private Sub UserForm_Initialize()
With ListView1
.View = lvwReport
.ColumnHeaders.Add , , "Number", 50
.ColumnHeaders.Add , , "Fruit", 50
For i = 1000 To 1 Step -1
.ListItems.Add(, , i).SubItems(1) = "Fruit" & i
Next
End With
End Sub
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
With ListView1
If ColumnHeader.Index = 1 Then
SortDataWithNumbers
Else
.Sorted = True
End If
End With
End Sub
Sub SortDataWithNumbers()
Dim sTemp As String * 10
Dim lvCount As Long
With ListView1
lvCount = .ListItems.Count
For i = 1 To lvCount
sTemp = vbNullString
If .SortKey Then
'RSet - right align a string within a string variable.
RSet sTemp = .ListItems(i).SubItems(.SortKey)
.ListItems(i).SubItems(.SortKey) = sTemp
Else
RSet sTemp = .ListItems(i)
.ListItems(i).Text = sTemp
End If
Next
.Sorted = True
For i = 1 To lvCount
If .SortKey Then
.ListItems(i).SubItems(.SortKey) = _
LTrim$(.ListItems(i).SubItems(.SortKey))
Else
.ListItems(i).Text = LTrim$(.ListItems(i))
End If
Next
End With
End Sub
In Action
Siddharth Rout code works great, but if you want to be able to sort all columns and some of them are numeric, you can use ColumnHeader.Index, and with the following code (source and credits: https://www.tek-tips.com/viewthread.cfm?qid=578008):
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
With ListView1
.Sorted = False
If .SortKey <> ColumnHeader.Index - 1 Then
.SortKey = ColumnHeader.Index - 1
Else
.SortOrder = 1 - .SortOrder
End If
'In the following line you specify the columns with numeric values
If ColumnHeader.Index = 1 Or ColumnHeader.Index = 7 Then
Dim S As String * 10, N As Integer
'justify the text using padding spaces
For N = 1 To .ListItems.Count
S = vbNullString
If .SortKey Then
RSet S = .ListItems(N).SubItems(.SortKey)
.ListItems(N).SubItems(.SortKey) = S
Else
RSet S = .ListItems(N)
.ListItems(N).Text = S
End If
Next
'sort column using "justified" text
.Sorted = True
'trim spaces from the text
For N = 1 To .ListItems.Count
If .SortKey Then
.ListItems(N).SubItems(.SortKey) = _
LTrim$(.ListItems(N).SubItems(.SortKey))
Else
.ListItems(N).Text = LTrim$(.ListItems(N))
End If
Next
Else
.Sorted = True
End If
End With
End Sub
I'm writing a Userform
What I am trying to achieve: while running my Userform with multiple selection checkboxes.
Collect all checked checkboxes captions along with its parent frame name
Filtering database on its first column with those collected strings
Loop through filtered cells and make the wanted sums
The selection can contain each row with different columns (Based on checkbox selection)
Coded for Estimate command button:
Private Sub preflight_calculate_Click()
Dim preflight_resource As Double, preflight_time As Double
preflight_resource = Val(Me.preflight_resource)
preflight_time = Val(Me.preflight_time)
Dim cell As Range
With ThisWorkbook.Sheets("Preflight")
With .Range("A1", .Cells(.Rows.Count, 1).End(xlUp))
.AutoFilter 1, Criteria1:=GetCheckedCaptions, Operator:=xlFilterValues
For Each cell In .SpecialCells(xlCellTypeVisible)
preflight_resource = preflight_resource + cell.Offset(, 6).Value
preflight_time = preflight_time + cell.Offset(, 8).Value
Next
End With
.AutoFilterMode = False
End With
With Me
.preflight_resource.Text = preflight_resource
.preflight_time.Text = preflight_time
End With
End Sub
Function GetCheckedCaptions() As Variant
Dim ctl As Control
With Me
For Each ctl In .Controls
If TypeName(ctl) = "CheckBox" Then
If ctl.Value Then
GetCheckedCaptions = GetCheckedCaptions & " " & ctl.Parent.Caption & "-" & ctl.Caption
End If
End If
Next
End With
GetCheckedCaptions = Split(Trim(GetCheckedCaptions))
End Function
Error code line:
preflight_resource = preflight_resource + cell.Offset(, 6).Value
Expected result:
For Example:
If I select the checkbox as follows US -> Mobile -> P0 and US -> Desktop -> P1
Output should be:
Textboxes below:
Resource Utilized: (F2 + G3) -> (0.73 + 0.62) -> 1.35 (Inside text box)
Time in Hours: (H2 + I3) -> (5.87 + 4.95) -> 10.82 (Inside text box)
How to achieve this?
I have a different approach to solve your question's problem.
If having a separate columns to store the values of each selection is an option, then check it out.
Summary of what happens in the spreadsheet:
Checkboxes data will be stored by VBA code in columns L to O
Cells L25 and N25 will sum total resources and time by adding the formulas (in each cell)
L25 -> =SUM(L2:M23)
N25 -> =SUM(N2:O23)
Here you can download the current file: https://1drv.ms/x/s!ArAKssDW3T7wlKMfhNyjEDsHmkxz-g
This will be the setup
The code behind the userform is as follows. Customize it reading each comment:
Option Explicit
Private Sub knightregression_yes_Change()
Application.EnableEvents = False
' Record values according to checkboxes checked in form
mUserForm.RecordCheckboxChange Me, Me.knightregression_yes, "Mobile", "Knight regression" ' In this case the task title is specified (last sub argument)
Application.EnableEvents = True
End Sub
Private Sub preflight_no_Click()
Application.EnableEvents = False
' Set userform's controls values depending on which one is calling the function
SetUserFormControlsValues Me, Me.preflight_no
Application.EnableEvents = True
End Sub
Private Sub preflight_yes_Click()
Application.EnableEvents = False
' Set userform's controls values depending on which one is calling the function
SetUserFormControlsValues Me, Me.preflight_yes
Application.EnableEvents = True
End Sub
Private Sub us_desktop_Change()
Application.EnableEvents = False
' Set userform's controls values depending on which one is calling the function
SetUserFormControlsValues Me, Me.us_desktop
Application.EnableEvents = True
End Sub
Private Sub us_dp0_Change()
Application.EnableEvents = False
' Record values according to checkboxes checked in form
mUserForm.RecordCheckboxChange Me, Me.us_dp0, "Desktop"
Application.EnableEvents = True
End Sub
Private Sub us_mobile_Change()
Application.EnableEvents = False
' Set userform's controls values depending on which one is calling the function
SetUserFormControlsValues Me, Me.us_mobile
Application.EnableEvents = True
End Sub
Private Sub us_mp0_Change()
Application.EnableEvents = False
' Record values according to checkboxes checked in form
mUserForm.RecordCheckboxChange Me, Me.us_mp0, "Mobile"
Application.EnableEvents = True
End Sub
Private Sub us_mp1_Change()
Application.EnableEvents = False
' Record values according to checkboxes checked in form
mUserForm.RecordCheckboxChange Me, Me.us_mp1, "Mobile"
Application.EnableEvents = True
End Sub
Private Sub us_mp2_Change()
Application.EnableEvents = False
' Record values according to checkboxes checked in form
mUserForm.RecordCheckboxChange Me, Me.us_mp2, "Mobile"
Application.EnableEvents = True
End Sub
Private Sub us_yes_Change()
Application.EnableEvents = False
' Set userform's controls values depending on which one is calling the function
SetUserFormControlsValues Me, Me.us_yes
Application.EnableEvents = True
End Sub
Private Sub UserForm_Initialize()
Dim formControl As MSForms.Control
' Clear preflight selections
ThisWorkbook.Worksheets("Preflight").Range("L2:O32").ClearContents
' Make all checkboxes unchecked and disabled except preflight test
For Each formControl In Me.Controls
If TypeOf formControl Is MSForms.CheckBox Then
If InStr(formControl.Name, "preflight") = 0 Then
formControl.Value = False
formControl.Enabled = False
End If
End If
Next
' Empty resource and time textboxes
Me.preflight_resource = vbNullString
Me.preflight_time = vbNullString
End Sub
Private Sub ComboBox2_Change()
Dim index As Integer
index = ComboBox2.ListIndex
lstAll.Clear
lstAll.MultiSelect = 2
lst_Added.MultiSelect = 2
Select Case index
Case Is = 0
With lstAll
Dim i As Long, LastRow As Long
LastRow = Sheets("Report").Range("A" & Rows.Count).End(xlUp).Row
If Me.lstAll.ListCount = 0 Then
For i = 2 To LastRow
Me.lstAll.AddItem Sheets("Report").Cells(i, "A").Value
Next i
End If
End With
Case Is = 1
With lstAll
.AddItem "No Task"
End With
Case Is = 2
With lstAll
.AddItem "No Task"
End With
End Select
End Sub
Private Sub Newfeatureyes_Click()
lstAll.MultiSelect = 2
lst_Added.MultiSelect = 2
Dim i As Long, LastRow As Long
LastRow = Sheets("NewFeature").Range("A" & Rows.Count).End(xlUp).Row
If Me.lstAll.ListCount = 0 Then
For i = 2 To LastRow
Me.lstAll.AddItem Sheets("NewFeature").Cells(i, "A").Value
Next i
End If
End Sub
Private Sub Newfeatureno_Click()
lstAll.Clear
lst_Added.Clear
mobileutilize = ""
mobilehours = ""
desktoputilize = ""
desktophours = ""
End Sub
Private Sub submitmobile_Click()
Dim i As Long, j As Long, LastRow As Long
Dim lbValue As String
Dim ws As Worksheet
If lst_Added.ListCount = 0 Then
MsgBox "Please add atleast 1 task"
Exit Sub
End If
mobileutilize = ""
mobilehours = ""
Set ws = ThisWorkbook.Sheets("NewFeature")
With ws
LastRow = .Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LastRow
For j = 0 To lst_Added.ListCount - 1
lbValue = lst_Added.List(j)
If .Cells(i, "A").Value = lbValue Or _
.Cells(i, "A").Value = Val(lbValue) Then
mobileutilize = Val(mobileutilize) + Val(.Cells(i, "F").Value)
mobilehours = Val(mobilehours) + Val(.Cells(i, "H").Value)
End If
Next
Next
End With
End Sub
Private Sub submitdesktop_Click()
Dim i As Long, j As Long, LastRow As Long
Dim lbValue As String
Dim ws As Worksheet
If lst_Added.ListCount = 0 Then
MsgBox "Please add atleast 1 task"
Exit Sub
End If
desktoputilize = ""
desktophours = ""
Set ws = ThisWorkbook.Sheets("NewFeature")
With ws
LastRow = .Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LastRow
For j = 0 To lst_Added.ListCount - 1
lbValue = lst_Added.List(j)
If .Cells(i, "A").Value = lbValue Or _
.Cells(i, "A").Value = Val(lbValue) Then
desktoputilize = Val(desktoputilize) + Val(.Cells(i, "G").Value)
desktophours = Val(desktophours) + Val(.Cells(i, "I").Value)
End If
Next
Next
End With
End Sub
Private Sub cmdAdd_Click()
If lstAll.ListCount = 0 Then
MsgBox "Select an item"
Exit Sub
End If
Dim i As Integer
For i = 0 To lstAll.ListCount - 1
If lstAll.Selected(i) = True Then lst_Added.AddItem lstAll.List(i)
Next i
End Sub
Private Sub cmdRemove_Click()
If lstAll.ListCount = 0 Then
MsgBox "Select an item"
Exit Sub
End If
Dim counter As Integer
counter = 0
For i = 0 To lst_Added.ListCount - 1
If lst_Added.Selected(i - counter) Then
lst_Added.RemoveItem (i - counter)
counter = counter + 1
End If
Next i
End Sub
Private Sub CommandButton1_Click()
Unload Me
Sheets("Estimation form").Select
Range("A1").Select
End Sub
Private Sub ComboBox1_DropButtonClick()
Dim i As Long, LastRow As Long
LastRow = Sheets("Report").Range("A" & Rows.Count).End(xlUp).Row
If Me.ComboBox1.ListCount = 0 Then
For i = 2 To LastRow
Me.ComboBox1.AddItem Sheets("Report").Cells(i, "A").Value
Next i
End If
End Sub
Also, add a module, name it: mUserForm and add this code:
Option Explicit
' Set userform's controls values depending on which one is calling the function
Public Sub SetUserFormControlsValues(mainUserForm As UserForm1, sourceControl As MSForms.Control)
Dim formControl As MSForms.Control
Dim enableMainCheckBoxes As Boolean
Dim enableMobileCheckBoxes As Boolean
Dim enableDesktopCheckBoxes As Boolean
Dim enableMPCheckboxes As Boolean
Dim enableDPCheckboxes As Boolean
Dim countryCode As String
Dim subcontrolList() As String
Dim counter As Integer
Select Case sourceControl.Name
' If preflight yes or no
Case "preflight_yes"
enableMainCheckBoxes = True ' xx_yes
enableMobileCheckBoxes = False ' xx_mobile
enableDesktopCheckBoxes = False ' xx_desktop
enableMPCheckboxes = False ' xx_mpx
enableDPCheckboxes = False ' xx_dpx
subcontrolList = Split("yes", ",")
Case "preflight_no"
enableMainCheckBoxes = False ' xx_yes
enableMobileCheckBoxes = False ' xx_mobile
enableDesktopCheckBoxes = False ' xx_desktop
enableMPCheckboxes = False ' xx_mpx
enableDPCheckboxes = False ' xx_dpx
subcontrolList = Split("yes", ",")
' If main box yes
Case "us_yes", "uk_yes", "jp_yes", "de_yes", "es_yes", "it_yes", "fr_yes"
enableMainCheckBoxes = True ' xx_yes
enableMobileCheckBoxes = sourceControl.Value ' xx_mobile
enableDesktopCheckBoxes = sourceControl.Value ' xx_desktop
enableMPCheckboxes = False ' xx_mpx
enableDPCheckboxes = False ' xx_dpx
countryCode = Left(sourceControl.Name, InStr(sourceControl.Name, "_") - 1)
subcontrolList = Split("mobile,desktop", ",")
' If mobile yes
Case "us_mobile", "uk_mobile", "jp_mobile", "de_mobile", "es_mobile", "it_mobile", "fr_mobile"
enableMainCheckBoxes = True ' xx_yes
enableMobileCheckBoxes = True ' xx_mobile
enableDesktopCheckBoxes = True ' xx_desktop
enableMPCheckboxes = True ' xx_mpx
enableDPCheckboxes = False ' xx_dpx
countryCode = Left(sourceControl.Name, InStr(sourceControl.Name, "_") - 1)
subcontrolList = Split("mp", ",")
' if desktop yes
Case "us_desktop", "uk_desktop", "jp_desktop", "de_desktop", "es_desktop", "it_desktop", "fr_desktop"
enableMainCheckBoxes = True ' xx_yes
enableMobileCheckBoxes = True ' xx_mobile
enableDesktopCheckBoxes = True ' xx_desktop
enableMPCheckboxes = False ' xx_mpx
enableDPCheckboxes = True ' xx_dpx
countryCode = Left(sourceControl.Name, InStr(sourceControl.Name, "_") - 1)
subcontrolList = Split("dp", ",")
End Select
For Each formControl In mainUserForm.Controls
If TypeOf formControl Is MSForms.CheckBox Then
' Set sub controls value
For counter = 0 To UBound(subcontrolList)
If sourceControl.Name = "preflight_yes" And InStr(formControl.Name, "preflight") = 0 And InStr(formControl.Name, countryCode & "_" & subcontrolList(counter)) > 0 Then
formControl.Enabled = True
formControl.Value = False
ElseIf sourceControl.Name = "preflight_no" And InStr(formControl.Name, "preflight") = 0 And InStr(formControl.Name, countryCode & "_" & subcontrolList(counter)) > 0 Then
formControl.Enabled = False
formControl.Value = False
ElseIf InStr(formControl.Name, "preflight") = 0 And InStr(formControl.Name, countryCode & "_" & subcontrolList(counter)) > 0 Then
formControl.Enabled = sourceControl.Value
formControl.Value = False
End If
Next counter
End If
Next
mainUserForm.releasenote_yes.Value = False
mainUserForm.automationfail_yes.Value = False
mainUserForm.knightregression_yes.Value = False
mainUserForm.releasenote_yes.Enabled = True
mainUserForm.automationfail_yes.Enabled = True
mainUserForm.knightregression_yes.Enabled = True
' Empty resource and time textboxes
mainUserForm.preflight_resource = vbNullString
mainUserForm.preflight_time = vbNullString
End Sub
' Record values according to checkboxes checked in form
Public Sub RecordCheckboxChange(mainUserForm As UserForm1, checkBoxControl As MSForms.CheckBox, formType As String, Optional exactTaskTitle As String)
' Declare objects
Dim resultRange As Range
' Declare other variables
Dim parentCaption As String
Dim checkboxCaption As String
Dim taskTitle As String
Dim resourceValue As Double
Dim timeValue As Double
Dim resourceColumn As Integer
Dim timeColumn As Integer
' Reset find parameters
Application.FindFormat.Clear
' Define which column to sum based on formType
Select Case formType
Case "Mobile"
resourceColumn = 5
timeColumn = 7
Case "Desktop"
resourceColumn = 6
timeColumn = 8
End Select
' Store the captions (parent and checkbox)
parentCaption = checkBoxControl.Parent.Caption
checkboxCaption = checkBoxControl.Caption
' If task title comes from code inside checkbox event, use it
If exactTaskTitle <> vbNullString Then
taskTitle = exactTaskTitle
Else
taskTitle = parentCaption & "*" & checkboxCaption
End If
' Find the parent and checkbox caption (using wildcards it's more simple)
Set resultRange = Sheets("Preflight").Range("A2:A32").Find(taskTitle, Lookat:=xlPart)
' If checkbox is checked record value
If checkBoxControl.Value = True Then
resourceValue = resultRange.Offset(0, resourceColumn).Value
timeValue = resultRange.Offset(0, timeColumn).Value
Else
resourceValue = 0
timeValue = 0
End If
' Store the value in spreadsheet
resultRange.Offset(0, resourceColumn + 6).Value = resourceValue
resultRange.Offset(0, timeColumn + 6).Value = timeValue
' Update the textboxes with totals
mainUserForm.preflight_resource = ThisWorkbook.Worksheets("Preflight").Range("L35").Value
mainUserForm.preflight_time = ThisWorkbook.Worksheets("Preflight").Range("N35").Value
' Reset find parameters
Application.FindFormat.Clear
End Sub
Hope you can help me... I have a displayed data on my listview. The column Headers are:
ROW ID CUSTOMER PICKUP DELIVERY LOAD PLACE BAGS AMOUNT STATUS -total of 10 columns
I want the forecolor in my column STATUS depends on the value. the value is either PAID or UNPAID, if PAID the color should be green and if UNPAID, the color should be red.
I have this code, but it not working for me, somebody will help me? Thank you in advance.
Private Sub UserForm_Activate()
Dim C As Long
Dim i As Long
Dim R As Long
ListView1.View = lvwReport
ListView1.HideSelection = False
ListView1.FullRowSelect = True
ListView1.HotTracking = True
ListView1.HoverSelection = False
ListView1.ColumnHeaders.Add Text:="Row", Width:=40
For C = 1 To 12
ListView1.ColumnHeaders.Add Text:=Cells(1, C).Text
ComboBox1.AddItem Cells(1, C).Text
Next C
**' |In this part of my code is not working|**
Dim Item As ListItem
Dim counter As Long
For counter = 1 To listView1.ListItems.Count
Set Item = listView1.ListItems.Item(counter)
If Item.SubItems(10) = "Paid" Then
listView1.ListItems.Item(counter).ListSubItems(10).ForeColor = vbGreen
End If
If Item.SubItems(10) = "Unpaid" Then
listView1.ListItems.Item(counter).ListSubItems(10).ForeColor = VBRed
Next counter
End Sub
listsubitime must be 9, since index numbers start at 0.
In my test, it work well.
Private Sub UserForm_Activate()
Dim C As Long
Dim i As Long
Dim R As Long
Dim li As ListItem
ListView1.View = lvwReport
ListView1.HideSelection = False
ListView1.FullRowSelect = True
ListView1.HotTracking = True
ListView1.HoverSelection = False
ListView1.ColumnHeaders.Add Text:="Row", Width:=40
For C = 1 To 12
ListView1.ColumnHeaders.Add Text:=Cells(1, C).Text
ComboBox1.AddItem Cells(1, C).Text
Next C
Dim vDB
vDB = Range("a1").CurrentRegion
For i = 2 To UBound(vDB, 1)
Set li = ListView1.ListItems.Add
For j = 1 To UBound(vDB, 2)
With li
.Text = i
.ListSubItems.Add , , vDB(i, j)
End With
Next j
Next i
'**' |In this part of my code is not working|**
Dim Item As ListItem
Dim counter As Long
For counter = 1 To ListView1.ListItems.Count
Set Item = ListView1.ListItems.Item(counter)
If Item.SubItems(9) = "Paid" Then
ListView1.ListItems.Item(counter).ListSubItems(9).ForeColor = vbGreen
End If
If Item.SubItems(9) = "Unpaid" Then
ListView1.ListItems.Item(counter).ListSubItems(9).ForeColor = vbRed
End If
Next counter
End Sub
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