Data Validation List Error - vba

I'm trying to add a data validation pulldown list, and I've been debugging it for a while to no avail. I'm getting a Run-time error 1004, Application-defined or object defined error. The error occurs in Formula1 setting part of the Validation.Add statement.
I've tried using a string reference to a named range, a string reference to a standard range, and, as shown below, a comma delimited list string generated from the list on the worksheet as shown in the code below. I have checked the list string with Debug.Print and got the expected result.
Sub addPT_Validation()
Dim sValidationList As String
Dim cell As Range
For Each cell In ThisWorkbook.Names("PT_Puldown").RefersToRange
sValidationList = sValidationList & cell.Value & ","
Next cell
sValidationList = Left(sValidationList, Len(sValidationList) - 1)
With ActiveSheet.Range("D14").Validation
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlEqual, _
Formula1:=sValidationList
.IgnoreBlank = True
.InCellDropdown = True
.ShowError = True
End With
End Sub
Thanks in advance for any guidance.

All your code is working (certainly could be optimized), all you need to do is delete the validation if it already exists.
If you try to add validation to a cell which already contains one, you will get error 1004.
Sub addPT_Validation()
Dim sValidationList As String
Dim cell As Range
For Each cell In ThisWorkbook.Names("PT_Puldown").RefersToRange
sValidationList = sValidationList & cell.Value & ","
Next cell
sValidationList = Left(sValidationList, Len(sValidationList) - 1)
With ActiveSheet.Range("D1").Validation
'/Delete first., in case of any any existing validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlEqual, _
Formula1:=sValidationList
.IgnoreBlank = True
.InCellDropdown = True
.ShowError = True
End With
End Sub

I'd use the named range reference to build up the formula to put in Formula1 parameter of Validation object Add() method, like follows
Sub addPT_Validation()
Dim formula As String
With ThisWorkbook.Names("PT_Puldown").RefersToRange
formula = "'" & .Parent.Name & "'!" & .Address(External:=False)
End With
With ActiveSheet.Range("D14").Validation
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlEqual, _
Formula1:=formula
.IgnoreBlank = True
.InCellDropdown = True
.ShowError = True
End With
End Sub

As pointed out by #cyboashu, your error is coming from the fact that you did not delete the validation before adding a new one.
With regard to your other issue of trying to pass the range to Formula1 directly:
Formula1 should refer to the range as a string.
eg:
Formula1:="=$G$2:$G$7"
or, using your variables:
Formula1:="=" & ThisWorkbook.Names("PT_Puldown").RefersToRange.Address
or, simpler:
Formula1:="=" & Range("PT_Puldown").Address

Related

How to alter code with FOR Each Loop to to avoid Error: 1004 No cells found

I have a macro that looks below header names for items if there is an item it will make it a drop down. Headers are in the 7th row so it starts looking from row 8 and on. The code runs perfectly, except if there is no items below the headers.
Sometimes the user does not need any drop downs for the sheet so they will leave all rows below the headers blank. Which is great for what I am doing but will make the macro throw errors as there is no items to be found.
I essentially need to tweak my code so it is able to stop or exit if no cells are found. This is the macro I need to tweak.
Sub AddDropDowns()
Dim cell As Range
Dim iDropDown As Long
With Worksheets("Sheet1")
For Each cell In .Range("B8", .Cells(8, .Columns.Count).End(xlToRight)).SpecialCells(XlCellType.xlCellTypeConstants)
AddDropDown Worksheets("DropDownsTT"), iDropDown, cell.Offset(-1).Value, "='" & .Name & "'!" & cell.Resize(WorksheetFunction.CountA(cell.EntireColumn) - 1).Address
Next cell
End With
End Sub
Not sure if this piece of code is needed but the macro calls the following subroutine:
Sub AddDropDown(sht As Worksheet, dropDownCounter As Long, header As String, validationFormula As String)
With sht.Range("A1").Offset(, dropDownCounter) '<--| reference passed sheet row 1 passed column
.Cells(1, 1) = header '<--| write header
With .Cells(2, 1).Validation '<--| reference 'Validation' property of cell 1 row below currently referenced one
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=validationFormula
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
dropDownCounter = dropDownCounter + 1
End Sub
You could do this:
Dim rng As Range
'...
With Worksheets("Sheet1")
On Error Resume Next
Set rng = .Range("B8", .Cells(8, .Columns.Count).End( _
xlToRight)).SpecialCells(XlCellType.xlCellTypeConstants)
On Error Goto 0
If Not rng Is Nothing Then
For Each cell In rng
AddDropDown Worksheets("DropDownsTT"), iDropDown, _
cell.Offset(-1).Value, "='" & .Name & "'!" & _
cell.Resize(WorksheetFunction.CountA(cell.EntireColumn) - 1).Address
Next cell
End If
End With
but that's kind of untidy, so I would probably use something like:
With Worksheets("Sheet1")
For Each cell In .Range("B8", .Cells(8, .Columns.Count).End( xlToRight))
If Len(cell.Value) > 0 Then
AddDropDown Worksheets("DropDownsTT"), iDropDown, _
cell.Offset(-1).Value, "='" & .Name & "'!" & _
cell.Resize(WorksheetFunction.CountA(cell.EntireColumn) - 1).Address
End If
Next cell
End With

Dynamic validation list - data from other worksheet

I have one worksheet where in a specified range should be validation list. This list is token from another worksheet (column A, from row 2 to last not-empty row). But it doesn't work and I can't figured why.
My code:
Set wsResourcesProjects = Sheets("ResourcesProjects")
Set wsProjects = Sheets("Projects")
With wsProjects.rGeneralFTERange.Offset(0, 3).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=ResourcesProjects!" & wsResourcesProjects.Cells(1, 1).CurrentRegion.Offset(1, 0).Address
.IgnoreBlank = True
.InCellDropdown = True
.ShowInput = True
.ShowError = True
End With
And in range rGeneralFTERange validation list is not appear. But when I change this part:
wsResourcesProjects.Cells(1, 1).CurrentRegion.Offset(1, 0).Address
on
"A2:A10"
then it's works. But it's not good for me, because data in column "A" are dynamic.
In your code Formula1:="=ResourcesProjects!" exclimation ! symbol might have created the problem, hope you have already created the named ranges :)
FYR named ranges
Sub validation()
'Select your range
Range("A1").Select
With Selection.validation
.Delete
'Month_Val is the namedrange name
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=Month_Val"
End With
End Sub

Setting cell data validation as list from a variable list

Am quite new to VBA and am piecing together my developments one step at at time searching for answers online but have hit a snag.
I'm struggling to understand how the creation of the data validation list code works. The beginning "With WrkBook.Range("H3").Validation" is where I'm putting the drop down list? Seems 'yes' from one posting, but another seemed to have the "With" followed by the actual range which contains the list. Secondly, the "Formula1:=..." I believe is also the location of the list. However, I seem to be only able to include the first cell in my list as being included in the list. Thanks in advance for any help.
Dim WrkBook As Worksheet
Dim LastCellRowNumber As Integer
Dim ListRng As Range
Dim Rng As Range
Set WrkBook = Worksheets("Misc Ref")
'Find
WrkBook.Activate
Range("A100000").Select
Range(Selection, Selection.End(xlUp)).Select
LastCellRowNumber = ActiveCell.Row
ActiveSheet.Cells(LastCellRowNumber, 1).Select
Set ListRng = WrkBook.Range(Cells(2, 1), Cells(LastCellRowNumber, 1))
With WrkBook.Range("H3").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:=WrkBook.ListRng
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
In this line:
Set ListRng = WrkBook.Range(Cells(2, 1), Cells(LastCellRowNumber, 1))
you already set or assign a Range Object referenced at WrkBook sheet object.
So you don't have to use WrkBook.ListRng in assigning the Formula1 argument.
Also, Formula1 argument is suppose to be the address of the source range in the form of string.
So it should be something like:
Formula1:= "=" & ListRng.Address
This will fail though if the worksheet your putting the validation list is not the same worksheet of the source list. So you might want to add:
Formula1:= "=" & ListRng.Address(, , xlA1, True)
That will give you the Sheet name as well. HTH.
Edit2: Based on comments and no need to use Split function.
Sub test()
Dim r As Range, lrow As Long
With Sheets("Misc Ref")
lrow = .Range("A" & .Rows.Count).End(xlUp).Row
Set r = .Range("A2:A" & lrow)
End With
'Debug.Print "=" & r.Address(, , xlA1, True)
With Sheets("Summary").Range("H10").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=" & r.Address(, , xlA1, True)
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
Setting the Address property External argument to True includes the full path.
But if you assign it to a validation formula, it automatically disregards the Workbook name.
So there is no need to use Split Function. No need to worry the apostrophe then. HTH.

Populate activeX comboboxes on different generated sheets (Excel 2007)

i'm a beginner and it's been days since i'm looking for a solution in vain, here's my issue:
In my excel file i should generate different sheets with a macro (already done).
Now on a specified column "L" on all of these generated sheets (starting from sheet number 9), i need an activeX combobox that would contain values brought from un unlimited column(A) of sheet(6).
I started by getting the values by adding values <> "" and storing them in an array.
it's not working, it's all messy, can someone please correct my code and help me, i'd appreciate any help .. thank you in advance
Option Explicit
Sub PicklistCopy()
Dim Nbre As Byte, Arr(), Liste As String, Cptr As Byte
Dim Current As Worksheet
Dim strSearch As String
Dim aCell As Range
strSearch = "Pick List Name"
For Each Current In Worksheets
Set aCell = Rows(1).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'copy pl values in an array
With Sheets("Pick Lists")
Nbre = Application.CountA(.Range("MyPL"))
ReDim Arr(1 To .Range("MyPL").Count)
Arr = Application.Transpose(.Range("MyPL"))
End With
'Get values diff from null
For Cptr = 1 To UBound(Arr)
If Arr(Cptr) <> "" Then Liste = Liste & Arr(Cptr) & ";"
Next
Liste = Left(Liste, Len(Liste) - 1)
With ActiveSheet.Range("L2:L4").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:=Liste
.IgnoreBlank = True
.InCellDropdown = True
End With
ActiveSheet.Range("L2:L4") = ""
Next
End Sub
I think what you are adding is Data Validation dropdown and not a regular dropdown. Below is my simple code to the the list under the validated cell.
Sub AddMyPl()
Dim ws As Worksheet
Dim strSearch As String
Dim aCell As Range
strSearch = "Pick List Name"
'This will loop thru my sheets in my workbook.
For Each ws In ActiveWorkbook.Worksheets
'skip the sheet that contains mylist
If ws.Name <> "mylist" Then
'get last row # in L column.
LastR = ws.Cells(Rows.Count, "L").End(xlUp).Row
'add validation from MyPL list to cells
With ws.Range("L2:L" & LastR).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=MyPL"
.IgnoreBlank = True
.InCellDropdown = True
End With
End If
Next ws
End Sub
I have 4 sheets. 'mylist' sheet contains MyPL range with the items for my dropdown. The loop will check all sheets which names is not "mylist" then will add the validation dropdown to range L2:L4.
Modify as needed.

VBA Create a validation based on the first character of the entry into a cell

Hi I am trying to create a cell validation in Excel through VBA. I am trying to do this through use of a wild card so that the validation in that cell will be based of the first character in the data entry.
Here is the Code I am working with.
Dim wild1 as string
wild1 = Cells(11, 7) Like "b*"
With Cells(11, 7).Validation
.Delete
.Add Type:=xlValidateCustom, AlertStyle:=xlValidAlertStop, Formula1:=wild1
End With
With the code above I get a validation error every time I try to type something into Cell(11, 7). How would I change this so that the data entry would be valid if the first character in the data entry in that cell starts with a b?
Thanks!
This is based on simoco's comment.........this event code goes in the worksheet code area:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ch As String
If Intersect(Target, Cells(11, 7)) Is Nothing Then Exit Sub
If Target.Count > 1 Then Exit Sub
ch = Left(Target, 1)
dq = Chr(34)
With Target.Validation
.Delete
.Add Type:=xlValidateCustom, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=left(A1,1)=" & dq & ch & dq
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
Application.EnableEvents = False
End Sub
and assumes G7 starts with no validation. Once a value is entered, the first letter is used in the validation.