简体   繁体   中英

Excel validation list from range + a single value

I have a list of names arranged in a table under the column BM Name . I want to add this to a validation list , which is working for me, however I also want to append/insert another value (preferably shown as the first value in the validation list).

I tried variations of the code below. For reasons I do not want to simply append the value to the original table as it is dynamically created from an external source.

Sub Val()
Dim tbl as ListObject
Dim ws as Worksheet
Set ws = ThisWorkbook.Sheets(1)

Set tbl = ws.ListObjects(1)
    With ws.Range("ChosenBM").Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
            xlBetween, Formula1:="=Sheet1!" & tbl.ListColumns("BM Name").DataBodyRange.Address
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
            xlBetween, Formula1:="Default BM" ' Code fails here
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
    End With ' Validation
End Sub

Add a different item on top of a Validation list

Referring to MS Help when using a xlValidateList type:

Formula1 must contain either a comma-delimited list of values or a worksheet reference to this list.

So instead of referring to a range you'll have to pass a comma-delimited list .

The shortest/fastest way (avoiding loops in the data range) would be to

  1. assign the needed values to an array and
  2. join them using a comma.

Step [1] is done easily via v = Application.Transpose(tbl.ListColumns("BM Name").Range) (BTW it's necessary to redimension from a 2-dim array to a "flat" one by transposing).

As you want to include another value in the first place, it's best not only to refer to the DataBodyRange , but to include the complete listobject range thus including its title row (row 1).

Eventually you'll have to change the column title ( "BM Name" ) to your special item's title ( "Default BM" ) via

v(1) = "Default BM"

Step [2] is executed by the right Formula1 argument Formula1:=Join(v, ",")

Further note: Of course it would have been possible to simply prefix the resulting list by the new item string separated by a comma:-)

Example call

Sub ValidateTableColumn()
Dim ws  As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim tbl As ListObject
Set tbl = ws.ListObjects(1)
With ws.Range("ChosenBM").Validation
      ' [1] Assign the needed values to a variant array (including the column title)
        Dim v
        v = Application.Transpose(tbl.ListColumns("BM Name").Range)
        v(1) = "Default BM"                 ' << Change first item to new one
        .Delete
      ' [2] pass a comma-delimited list by applying Join() function to the array
        .Add Type:=xlValidateList, _
             AlertStyle:=xlValidAlertStop, Operator:=xlBetween, _
             Formula1:=Join(v, ",")          ' << pass the comma-separated list
        .ShowInput = True
        .ShowError = True
    End With ' Validation
End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM