Excel VBA: Listbox Error when assigning Linked Cell - vba

I have some cells with Data Validation. Because the dropdown list is small and hard to read, I have a button which opens a list box and populates it with the cell's Data Validation list.
Dim btnAddToList As OLEObject
Public lboTemp As OLEObject
Set btnAddToList = ws.OLEObjects("btnAddToList")
Set lboTemp = ws.OLEObjects("TempListBoxS")
Set Field = Selection ' This is always cell $D$1, $D$2, or $D$3
btnAddToList.Visible = False
'Create a named range "temp"
ActiveWorkbook.Names.Add Name:="temp", RefersTo:=Field.Validation.Formula1
' open list box
' position list box
' load it with "temp"
With lboTemp
'show the listbox with the list
.Visible = True
.Left = Field.Left
.Top = Field.Top + 50
.ListFillRange = "temp"
.Object.MultiSelect = 0 ' Single select
On Error GoTo errHandler
prev = .LinkedCell
If prev <> "" Then prev = prev & ": " & Range(.LinkedCell).Value ' for debugging
.LinkedCell = Field.Address 'SOMETIMES THIS GIVES Err 440: could not set property value, invalid property value
.Width = Field.Width + 5
.Height = WorksheetFunction.Min(270, .Object.ListCount * 20) 'field.Height + 5
End With
As noted in the comment above, I sometimes, but not always, I get an error when the LinkedCell is supposed to be populated by with the Field.Address.
This code is used by six different cells (D1:D3 on two different worksheets), but the error only appears to occur when one of the D1 cells is the one selected. Those cells have one other thing in common: their data validation lists, respectively, are:
='Category Table'!$F$2:$F$31 and
='Category Table'!$F$32:$F$41
The other four cells -- which don't get the error -- use a complicated dynamic range that references a different table on the "Category Table" sheet. (I don't really think this has anything to do with my problem, but I don't see anything else those cells have in common)
If no one can give me an answer, I'd appreciate some advice on how to track down an intermittent problem.
Thanks!

Maybe the problem is the return of Field.Address. The .Adress property returns, by default, with the absolute value of row and column. You can try Field.Address(RowAabsolute:=false, ColumnAbsolute:=false) . Hope this help.
and sorry my english.

I managed to stop this issue by ensuring that the linked cell was empty before creating the reference.

Related

How to Create a Simple Userform with Checkboxes in VBA

I am extremely new to VBA and am trying to create a spreadsheet that uses a checkbox userform to populate a table in a spreadsheet. I have been able to get the table to populate, but if a box is accidentally checked and is unchecked, the table remains populated. How do I get the table to go back to being blank after a box is unchecked and what is an efficient way to code the 33 checkboxes to populate the 33 spaces in the spreadsheet. Please see the images attached to aid in my description.
Thanks,
Userform Image
Spreadsheet Image
Setting the CheckBox ControlSource Property to a range address will link it to the range. If the range isn't qualified A1 the Checkbox will link to the Worksheet that is the ActiveSheet when the Userform Opens. To qualify the address add the Range's parent Worksheet's Name in single quotes followed by a exclamation mark and finally the ranges relative address 'Check List'!A1.
Initially, the Checkbox will be grayed out indicating that the linked cell is empty. When you check and uncheck it the linkedcell value will toggle between True and False.
Demo Userform Code
Private Sub UserForm_Initialize()
Dim Left As Single, Top As Single
Dim cell As Range, row As Range, check As MSForms.CheckBox
Top = 25
Left = 25
With Worksheets("Check List")
For Each row In .Range("A2:K4").Rows
For Each cell In row.Cells
Set check = Me.Controls.Add("Forms.CheckBox.1")
With check
.ControlSource = "'" & cell.Parent.Name & "'!" & cell.Address(RowAbsolute:=False, ColumnAbsolute:=False)
.Left = Left
.Top = Top
Left = Left + 12
End With
Next
Left = 25
Top = Top + check.Height + 2
Next
End With
End Sub

VBA Form - Vlookup cell and assign value to that cell

Encountering an issue in a VBA regarding vlookup function.
I have 2 comboboxes and 6 Textboxs for user input.
I want to use a vlookup (or index,Match(),Match()) to look up a cell in a data table and assign the values from the textboxes to these cells.
When I run the code for what I believe should work, it is returning object errors.
Private Sub CommandButton2_Click()
Dim MonthlyTable As Range
Set MonthlyTable = Sheets("DATA Monthly").Range("A6:AE400")
Dim ColumnRef As Range
Set ColumnRef = Sheets("Drivers").Range("N11")
' Assign CB2 value to M11 cell reference so it can be converted to a column ref in N11.
Sheets("Drivers").Range("M11").Value = ComboBox2.Value
Dim CB1Value As String
CB1Value = "Joiners" & ComboBox1.Value
Dim CB2Value As String
CB2Value = ComboBox2.Value
MsgBox CB1Value & " " & CB2Value
Dim tb1value As Range
tb1value = Application.WorksheetFunction.VLookup(CB1Value, MonthlyTable, ColumnRef, False)
tb1value.Value = TextBox1.Value
Unload Me
End Sub
I am at a loss for what to do here as I feel like it should be this simple!
Thanks in advance.
Edit. Further digging indicates that you cannot select a cell you are vlookup'ing as this commands only returns a value it does not actually select the cell for my intents and purposes.
not really clear to me you actual aim, but just following up your desire as stated by:
I want to use a vlookup (or index,Match(),Match()) to look up a cell
in a data table and assign the values from the textboxes to these
cells
you may want to adopt the following technique:
Dim tb1value As Variant '<--| a variant can be assigned the result of Application.Match method and store an error to be properly cheeked for
tb1value = Application.Match(CB1Value, MonthlyTable.Column(1), 0) '<--| try finding an exact match for 'CB1Value' in the first column of your data range
If Not IsError(tblvalue) Then MonthlyTable(tb1value, columnRef.Value).Value = TextBox1.Value '<--| if successful then write 'TextBox1' value in data range cell in the same row of the found match and with `columnRef` range value as its column index
Excel uses worksheet functions to manipulate data, VBA has different tools, and when you find yourself setting cell values on a sheet via VBA so that some worksheet function can refer to them it is time to look for a true VBA solution. I suggest the following which, by the way, you might consider running on the Change event of Cbx2 instead of a command button.
Private Sub Solution_Click()
' 24 Mar 2017
Dim MonthlyTable As Range
Dim Rng As Range
Dim Lookup As String
Dim Done As Boolean
Set MonthlyTable = Sheets("DATA Monthly").Range("A2:AE400")
' take the lookup value from Cbx1
Lookup = ComboBox1.Value
Set Rng = MonthlyTable.Find(Lookup)
If Rng Is Nothing Then
MsgBox Chr(34) & Lookup & """ wasn't found.", vbInformation, "Invalid search"
Else
With ComboBox2
If .ListIndex < 0 Then
MsgBox "Please select a data type.", vbExclamation, "Missing specification"
Else
TextBox1.Value = MonthlyTable.Cells(Rng.Row, .ListIndex + 1)
Done = True
End If
End With
End If
If Done Then Unload Me
End Sub
There are two points that need explanation. First, the form doesn't close after a rejected entry. You would have to add a Cancel button to avoid an unwanted loop where the user can't leave the form until he enters something correct. Note that Done is set to True only when the search criterion was found And a value was returned, and the form isn't closed until Done = True.
Second, observe the use of the ListIndex property of Cbx2. All the items in that Cbx's dropdown are numbered from 0 and up. The ListIndex property tells which item was selected. It is -1 when no selection was made. If you list the captions of your worksheet columns in the dropdown (you might do this automatically when you initialise the form) there will be a direct relationship between the caption selected by the user (such as "Joiners") and the ListIndex. The first column of MonthlyTable will have the ListIndex 0. So you can convert the ListIndex into a column of MonthlyTable by adding 1.
I think it is better to use "find" in excell vba to select a cell instead of using vlookup or other methods.

set ActiveX checkbox properties with VBA word 2010

I have searched high and low for this, but no luck.
To create a checkbox:
Selection.InlineShapes.AddOLEControl ClassType:="Forms.CheckBox.1"
However, there are several properties associated with a checkbox, and I wanted to find out how to set them as well when I am creating the checkbox.
For example, I tried this:
Selection.InlineShapes.AddOLEControl ClassType:="Forms.CheckBox.1", Caption:=""
But the code throws a "Named Argument Not Found" error while highlighting Caption:=""
For anyone with the same issue
'to place it in the table, assuming only 1 table, and in this example the checkbox is placed in the second Row, first Column
ActiveDocument.Tables(1).Cell(2, 1).Select
Set myOB = Selection.InlineShapes.AddOLEControl(ClassType:="Forms.CheckBox.1")
With myOB.OLEFormat
.Activate
Set myObj = .Object
End With
With myObj
'now you can name the field anything you want
.Name = "CB1"
.Value = False
'delete the caption, or have it say what you want
.Caption = ""
.Height = 22
.Width = 22
End With

Find invalid data validation cells

Description:
I have created a custom dropdown data validation list where I can choose among several values. These values on the dropdown list changes as I need (are defined in a worksheet column X).
Problem:
My problem occurs when I choose one of those values, let say Y, from the dropdown list and then I update the data validation by removing the last inserted value (deleted the Y value from column X). By doing this the value Y present in the worksheet is no longer valid so I would like to know if there is a way to obtain a list (array or string) of cells with the invalid data.
What I have done/thought so far:
I have searched in several sites and read similar questions but I cannot find anything usefull. I thought about looping all the cells and check if the value is valid but since I have a huge amount of data I think that it is not the best approach.
Since Excel already mark these invalid data with a red circle maybe it could be possible to get the address of those marked cells?
Thanks in advance!
The correct way to obtain the invalid cells in a worksheet is using Cells.SpecialCells(xlCellTypeAllValidation).
By using some information present in Microsoft KB213773 (Q213773) - "How to create data validation circles for printing in Excel" a similar Sub can be used to loop all invalid cells and then change their values (or mark them to future edit).
Sub CorrectInvalidValues()
Dim data_range As Range
Dim invalid_cell As Range
Dim count As Integer: count = 0
Dim nr_invalid As Integer: nr_invalid = 0
Dim new_value As String
'If an error occurs run the error handler and end the procedure
On Error GoTo errhandler
Set data_range = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo 0
' Loop through each cell that has data validation and gets the number of invalid cells
For Each invalid_cell In data_range
If Not invalid_cell.Validation.Value Then
nr_invalid = nr_invalid + 1
End If
Next
' Editing each value
For Each invalid_cell In data_range
If Not invalid_cell.Validation.Value Then
count = count + 1
Application.Goto reference:=invalid_cell, Scroll:=True
new_value = Application.InputBox("Please insert a correct value.", "Invalid Data " & count & "/" & nr_invalid)
If Not (new_value = "False") Then
invalid_cell.Interior.ColorIndex = 0
invalid_cell.Value = new_value
Else
invalid_cell.Interior.Color = RGB(255, 0, 0)
invalid_cell.Value = "<PLEASE EDIT>"
End If
End If
Next
Exit Sub
errhandler:
MsgBox "There are no cells with data validation on this sheet."
End Sub

How to determine if there are hidden columns when copying in Excel VBA

As the title explains, I have an Excel 2003 workbook and I'm copying a number of columns of one sheet to another in VBA. Unknown to me, someone has hidden a few columns on the source sheet and it has messed up how I process the cells in the destination sheet.
How can I programmically determine:
IF there are hidden columns
WHICH columns are hidden?
Thanks!
JFV
For a Range, check the Range.Hidden property.
The following snippet from MSDN is a good example of how to hide/unhide a row/column:
Worksheets("Sheet1").Columns("C").Hidden = True
You can also test the value with an If statement:
For ColCounter = 1 To 10
If Columns("C").Hidden = True Then
Columns("C").Hidden = False
End If
Next
If you only want to copy the visible files then one option that is quite nice it to select only the visible columns as a range.
This can be done by
Set visrng =rng.SpecialCells(xlCellTypeVisible)
It wasn't clear to me if this would be useful in your case, but I decided to post it as it could be useful to others.
Copying Visible Cells to another Range and then comparing the number of cells in each is probably the easiest way to determine if there are Hidden Cells in the Range
eg
Selection.SpecialCells(xlCellTypeVisible).Copy Destination:=VisRan
If Not Selection.Cells.Count = VisRan.Cells.Count Then
MsgBox "Selection contains Hidden Cells"
End If
You can check by using a function like:
Function IsColumnHidden(column As Variant) as Boolean
IsColumnHidden = False
If Columns(column).ColumnWidth = 0.0 Then IsColumnHidden = True
End Function
A Column width or Row height of 0.0 is an indicator of whether or not the range is hidden.
Here is one that I have tested and it works well if you want to hide/unhide columns
Sub Macro1_Test_Hidden() ' ' Macro1_Test_Hidden Macro ' ' ' If Columns("BH:XFA").Hidden = False Then Columns("BH:XFA").Select Range("BH:XFA").Activate Selection.EntireColumn.Hidden = True Else Columns("BH:XFA").Select Range("BH:XFA").Activate Selection.EntireColumn.Hidden = False End If ' ' End Sub