Need help, VBA, need the combobox to avoid entering a specific values - vba

I have a list of data in a sheet from A1:A8 and i have a combobox1 in a userform. What i want is to avoid a user to input an invalid value in the combobox1 based on the lists of data in the sheet

Go to combobox properties and change Style from 0 - fmStyleDropDownCombo to 2 - fmStyleDropDownList

i think this is what you are searching:
https://msdn.microsoft.com/en-us/vba/access-vba/articles/combobox-beforeupdate-event-access
There you have a way to check the values with that you want, there is a example where you can replace it with your range of cells.
Edited (Nice point, i'll put the example here):
Private Sub Combobox_BeforeUpdate(Cancel As Integer)
For i = 1 to 8
If(Cells(i, 1).Value == Me.Combobox.Value)
Cancel = True
Me.Combobox.Undo
End If
Next i
End Sub
Cya.

Related

Userform listbox that depends on another listbox

I have been looking in the internet for the answer to this, but mostly people say to use data validation, which doesn't really solve my problem. What I'm trying to do is, lets say that I have ListBox1, which has 3 values (red, blue, green) and there's another listbox (ListBox2) where I want value of a list from a worksheet to appear depending on the answer of the first ListBox. For example: I select red from listbox1 and then I want to have the options from the list "red" (apple, coke,fire) in listbox2.
I would greatly appreciate some help in this. Thanks
you could use something like follows (adapt it as per your needs):
Private Sub ListBox1_Click()
With Me.ListBox2
.Clear
.List = Application.Transpose(GetColorItemsRange(Me.ListBox1.value)) 'fill referenced listbox with values from the range returned by GetColorItemsRange function
End With
End Sub
Function GetColorItemsRange(colorValue As String) As Range
With Worksheets("ColorItames") ' change "ColorItames" with actual name of your worksheet with items associated to colors
With .Range("A1", .Cells(1, .Columns.Count).End(xlToLeft)).Find(what:=colorValue, LookIn:=xlValues, lookat:=xlWhole) 'find and reference the referenced sheet row 1 cell matching the passed value
Set GetColorItemsRange = .Parent.Range(.Cells.Offset(1), .Cells.End(xlDown)) 'return the range ranging from referenced range down to last not empty cell before first empty cell
End With
End With
End Function
Data validation is the way to go. You would want to leverage some combination of VBA to adjust the range listbox2 is using after Listbox1 is updated. This is relatively easy if only 1 selection is used on listbox1.
Hopefully you just have one selection, so you could do the following code:
Private Sub ListBox1_Click()
If ListBox1.Selected(0) = True Then
'Selection is apple. Adjust DynamicRange name for A1:A3
ThisWorkbook.Names("DynamicRange").RefersTo = Range("A1:A3")
ElseIf ListBox1.Selected(1) = True Then
ThisWorkbook.Names("DynamicRange").RefersTo = Range("B1:B3")
ElseIf ListBox1.Selected(2) = True Then
ThisWorkbook.Names("DynamicRange").RefersTo = Range("C1:C3")
End If
End Sub
This is based on a setup that looks like this:
Here's what both listbox properties would look like:
If you want to download this classy template, click here.

Excel VBA: Accessing the individual fields in a selected ListBox row

I am trying to access the individual cells in a selected/highlighted ListBox "lstData" row so I can reference their values elsewhere.
When I set a watch for Me.lstData.SelectedItem, I get Expression not defined in context. Same with Me.lstData.SelectedIndex and Me.lstData.Rows(1). The only thing that kind of works for me is Me.lstData.Value, but it ONLY returns the leftmost cell. When I try to plug it into the =OFFSET function
=Offset(Me.lstData.Value, ,1,1)
to access the cell immediately to the right, I get Expression not defined in context again.
How can I reference the other selected cells?
I don't think you can use Offset on a ListBox form control. The way to reference a 'cell' in a multi-column ListBox is by indexing the List property.
Here, i returns the row of the selected item, and 1 represents the second column (base 0) of the listbox:
Option Explicit
Private Sub CommandButton1_Click()
Dim i As Long
With Me.ListBox1
i = .ListIndex
MsgBox .List(i, 1)
End With
End Sub
Private Sub UserForm_Initialize()
With Me.ListBox1
.AddItem "A"
.List(0, 1) = "Alpha"
.AddItem "B"
.List(1, 1) = "Beta"
End With
End Sub

VBA - Listbox and Data

I have a listbox called listbox1 that shows me the data in sheet1 but the problem is that it doesn't show me all of the data sometimes i have 3000 line of data and it shows me anlo first 50 line this is the code i am using if someone can help please :
ListBox1.List = Sheets("Sheet1").Range("A1:F3000").Value
if you need datas from one column only then you'd go:
ListBox1.List = Application.Transpose(Sheets("Sheet1").Range("A1:A3000")) '<== change "A"s in Range("A1:A3000") to wanted column index
otherwise if you want to list data from more columns you have to go like this:
Private Sub UserForm_Initialize()
Dim Data As Variant
...
Data = Sheets("Sheet1").Range("A1:F3000")
With UserForm1.ListBox1 '<== change it with actual UserForm and ListBox names
.ColumnCount = 2
.List = Data
End With
but you'd be able to select one or more (up to ListBox MultiSelect property setting) entire row, and not single "cells".
Try changing the properties of the listbox to the range you need. Then change ColumnCount to 6.
Ie:
To make the RowSource dynamic, input 6 on the ColumnCount proterty and delete the range in the RowSource property and add this code to the form.
Private Sub UserForm_Initialize()
ListBox1.RowSource = Sheets("Sheet1").Range("A1:F3000").Address(external:=True)
End Sub

Listbox Modification in VBA

I created a Userform in Word which imports 3 columns of data from an excel sheet, inserts it into bookmarks and in the name of the word document and saves it as a pdf.
Now I wanted to add a Listbox into the form to be able to add, modify and delete the inputs manually which are usually imported from the excel sheet .
I already figured out how to add data from 3 textboxes into a 3 Column Listbox but even after googling for hours I can't find a good way to modify selected data.
VB.net has the .selectedItem property, VBA does not. Can anybody give me an example how to modify a multi column listbox with the values of 3 textboxes?
Thanks in advance
You need to iterate through ListBox.Selected and check if it is True. Once you get a True one, you can process that item.
Sample code adds some items with columns and sets up a click event to run through the Selected items.
Private Sub ListBox1_Click()
Dim i As Integer
For i = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(i) Then
Debug.Print ListBox1.List(i, 0)
End If
Next i
End Sub
Private Sub UserForm_Initialize()
ListBox1.AddItem "test"
ListBox1.AddItem "test1"
ListBox1.AddItem "test2"
ListBox1.ColumnCount = 3
ListBox1.ColumnHeads = True
ListBox1.List(1, 0) = "change to 1,0"
ListBox1.List(1, 1) = "change to 1,1"
ListBox1.List(1, 2) = "change to 1,2"
End Sub
Picture of form with Immediate window after clicking each item in turn.

Detecting changes to checkboxes via VBA

Following on from my previous question.
A requirement from the customer is to have checkboxes on a report to disable rows of information on another sheet. The rows are defined as named ranges, formated by P_XXXXXX. The XXXXXX is a unique identifier that is also a field on the row so I can easily generate the range names on the fly.
The problem I am having is:
After clicking on the items and then closing the form Excel asks if we want to save. This is undersirable.
I need someway of registering a change event happening on my generated checkboxes. So if one or more changes I can run through and hide/unhide the relevant ranges.
My code for adding the checkboxes looks like:
' For each row...
' check box in column 17(=Q).
Dim lCenter As Long
lCenter = rngCurrent.Width / 4 ' not actual centre but close enough
With ActiveSheet.CheckBoxes.Add(rngCurrent.Left + lCenter, rngCurrent.Top - 2, rngCurrent.Width, rngCurrent.Height)
.Interior.ColorIndex = xlNone
.Caption = ""
End With
So how do you link a change in a checkbox with a sub/function?
Set the OnAction property of the Checkboxes object to the name of a sub you want to run whenever the checkbox is checked or unchecked.
Sub MakeCB()
With ActiveSheet.CheckBoxes.Add(ActiveCell.Left + 0, ActiveCell.Top - 2, ActiveCell.Width, ActiveCell.Height)
.Interior.ColorIndex = xlNone
.Caption = ""
.OnAction = "CheckboxChange"
End With
End Sub
Sub CheckboxChange()
MsgBox "change"
End Sub
I don't think there are any events available with the Excel.Checkbox control. Try using the MSForms checkbox instead. You'll need a reference to 'Microsoft Forms 2.0 Object Library' - it's not redistributeable, but if you're using VBA, then that's fine.
You can then do something like this, and handle the event in the usual way:
''class level
Private WithEvents m_Checkbox as MSForms.CheckBox
Public Sub MakeCheckbox()
Set m_Checkbox = Activesheet.OLEObjects.Add("Forms.Checkbox.1")
End Sub
Private Sub m_Checkbox_Click()
''Do stuff
End Sub
Obviously, you'll only be able to handle a set number of checkboxes this way - I would recommend creating a class to hold each checkbox.