Динамически генерировать массив лет для списка проверки данных Excel VBA - PullRequest
2 голосов
/ 01 ноября 2019

Я добавляю раскрывающийся список Проверка данных в ячейку таблицы и хочу динамически заполнить ее массивом Years, начиная с Today()+1 до 10 years back. например, 2020,2019,2018,2017,2016,2015,2014,2013,2012,2011,2010. Я попытался использовать сокращение для Evaluate, то есть [], но по некоторым причинам я получаю ошибку 2015.

    With .ListColumns("Select Year").DataBodyRange
        With .Cells(1).Validation
            .Delete
            '.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="<Year>,2020, 2019,2018,2017,2016,2015,2014,2013,2012,2011,2010"
            .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=[Transpose(Text(date( (year(today())+1) + row(1:10), 1, 1), "yyyy"))]
            .IgnoreBlank = True
            .InCellDropdown = True
            .InputTitle = ""
            .ErrorTitle = ""
            .InputMessage = ""
            .ErrorMessage = ""
            .ShowInput = True
            .ShowError = True
        End With
        .Cells(1).Value2 = "<Year>"
    End With

Формула:

Formula1:=[Transpose(Text(date( (year(today())+1) + row(1:10), 1, 1), "yyyy"))]

Почему этоне работает вдруг? Есть ли альтернативный быстрый способ генерировать годы?

Вот скриншот, который я добавил ниже. Он работал раньше, пока я не запустил следующий код:

Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
If Target.Name = "Instructions" Then
    ThisWorkbook.Sheets("Instructions").Visible = True
    Target.Follow ' here is where error occurred and evaluate stopped working!
End If
End Sub

enter image description here

Ответы [ 2 ]

4 голосов
/ 01 ноября 2019
  1. Ваша математика неверна:
[Transpose(Text(date( (year(today())+2) - row(1:10), 1, 1), "yyyy"))]
При использовании xlValidateList он ожидает список с разделителями-запятыми, а не массив. Поэтому создайте и массив переменных и используйте Join:
    Dim arr As Variant
    arr = [Transpose(Text(date( (year(today())+2) - row(1:10), 1, 1), "yyyy"))]


     With .ListColumns("Select Year").DataBodyRange
        With .Cells(1).Validation
            .Delete
            '.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="<Year>,2020, 2019,2018,2017,2016,2015,2014,2013,2012,2011,2010"
            .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(arr, ",")
            .IgnoreBlank = True
            .InCellDropdown = True
            .InputTitle = ""
            .ErrorTitle = ""
            .InputMessage = ""
            .ErrorMessage = ""
            .ShowInput = True
            .ShowError = True
        End With
        .Cells(1).Value2 = "<Year>"
    End With

Вместо заполнения массива формулой, а не простым циклом:

Dim arr(1 To 10) As Long

Dim i As Long
For i = 1 To 10
    arr(i) = Year(Date) + 2 - i
Next i
2 голосов
/ 01 ноября 2019

Определите именованный диапазон в области рабочей книги с помощью выражения в квадратных скобках:

'Years' refers to '=TRANSPOSE(TEXT(DATE((YEAR(TODAY())+1)+ROW...'

Теперь ваша формула проверки данных может быть просто =Years.

Основное правило: избегайте использования выражений в квадратных скобках в коде VBA. Это хорошо для одноразового кода и инструкций отладчика в непосредственной панели, а не для производственного кода.

...