Массивоподобный оператор для нескольких AND в операторе IF - PullRequest
2 голосов
/ 29 апреля 2020

Есть ли способ улучшить ниже? Я хотел бы знать, может ли выражение, похожее на массив, заменить нижеследующее.

Я просто хочу удалить несколько «И не», так что если вы можете предложить что-то для оптимизации ниже, я был бы признателен .


    Set ws_raw = ThisWorkbook.Worksheets("Raw")
    Set ws_master_tracker = ThisWorkbook.Worksheets("Master Tracker")
    ' more assignments here...

    For Each ws In ThisWorkbook.Worksheets

        If Not ws Is ws_raw _
            And Not ws Is ws_master_tracker _
            And Not ws Is ws_title_page _
            And Not ws Is ws_sample _
            And Not ws Is ws_closing _
            And Not ws Is ws_ref _
            And Not ws Is ws_pdf_template _
            And Not ws.Visible = xlSheetHidden Then

            project_name = ws.Range("E3").Value
            int_last_row_of_ws = 46

            For int_current_row_of_ws = 11 To int_last_row_of_ws
                cell_value = ws.Cells(int_current_row_of_ws, 3).Value

                With rng_raw
                    .AutoFilter 1, project_name
                End With

                Set rng_filtered_raw = ws_raw.Range("J3", ws_raw.Cells(int_last_row_of_raw, int_last_col_of_raw)).SpecialCells(xlCellTypeVisible)

                Select Case cell_value

                    Case Is = "Task Creation!"
                        module_to_look_for = "Task Creation"
                    ' twenty more cases

                    ' Others that are manually typed
                    Case Else
                        module_to_look_for = "MANUAL"

                End Select

                If Not rng_filtered_raw Is Nothing Then

                    If module_to_look_for = "MANUAL" Then
                        ' Do nothing
                        ' Highlight cell, etc.
                    Else
                        look_up_result = Application.WorksheetFunction.VLookup(module_to_look_for, rng_filtered_raw, 3, False)

                        If look_up_result = "" Then
                            ws.Cells(int_current_row_of_ws, 56).Value = "Blank Date!"
                        Else
                            ws.Cells(int_current_row_of_ws, 56).Value = look_up_result
                        End If
                    End If

                End If

            Next int_current_row_of_ws

        End If

    Next ws

Что-то вроде:

Dim some_array_variable As Array
Set some_array_variable = (ws_master_tracker, ws_title_page, .....)

If Not ws Is In some_array_variable Then
' some code...

Пожалуйста, помогите, я новичок в VBA.

Ответы [ 2 ]

3 голосов
/ 29 апреля 2020

Это зависит от типа используемой переменной. Это проверяет основные цвета:

Sub MultiAND()

    kolor = "mauve"

    If Not kolor = "red" And Not kolor = "blue" And Not kolor = "yellow" Then
        MsgBox "secondary"
    Else
        MsgBox "primary"
    End If
End Sub

, поскольку переменные являются строками, цепочка AND NOT может быть заменена на:

Sub StringMeAlong()
    kolor = " mauve "
    s = " red blue yellow "
    If InStr(s, kolor) = 0 Then
        MsgBox "secondary"
    Else
        MsgBox "primary"
    End If
End Sub

Вот простой тест простых чисел для чисел меньше 100:

Sub IsItPrime()
    s = "|1|2|3|5|7|11|13|17|19|23|29|31|37|41|43|47|53|59|61|67|71|73|79|83|89|97|"
    N = 23
    v = "|" & CStr(N) & "|"
    If InStr(s, v) = 0 Then
        MsgBox "not prime"
    Else
        MsgBox "Prime"
    End If
End Sub

Если бы это было в формуле рабочего листа, вы могли бы использовать функцию MATCH() с константами массива.

2 голосов
/ 29 апреля 2020

Вы можете использовать метод фильтра массива для проверки существования:

dim arrSheets() as string
arrSheets = Split("sheetNameOne,sheetNameTwo,sheetNameThree", ",")
if ubound(filter(arrsheets,"sheetNameOne"))>-1 then debug.print "Sheet is in list"

Редактировать: расширенный ответ по запросу ...

Я использовал имена листов для краткости, а не объекты листа так как вам просто нужно перечислить имена листов в строке через запятую. Чтобы использовать фактические объекты, как вы это сделали в своем коде, вам необходимо присвоить их массиву, например так:

Dim arrSheets(3) as string
arrSheets(0) = ws_master_tracker.name
arrSheets(1) = ws_title_page.name
arrSheets(2) = ws_sample.name

Вместо строки;

arrSheets = Split("Master Tracker,Title Page,Sample Sheet", ",")

Split метод берет строку и разбивает ее на элементы массива на основе разделителя, в приведенном выше примере запятая. Представьте себе текст в столбцы в Excel.

Свойство Ubound описывает количество элементов в массиве - три в этом примере. Он основан на нуле, т. Е. 1 экземпляр вернет 0, 2 экземпляра = 1, 3 = 2 и т. Д.

Метод Filter возвращает новый массив, содержащий только элементы, соответствующие указанным критериям, в этом case заданное c имя листа. Как прокомментировал Тим Уильямс, метод будет включать подстроки, поэтому, если у вас есть лист с именем «мой лист», а другой с именем «какой-то другой лист», фильтрация по слову «лист» вернет оба.

Соединение их вместе: Split создает массив из строки, фильтрация возвращает массив, содержащий запрашиваемую строку (и), Ubound сообщает, сколько раз эта строка находится в фильтруемом массиве. Если его нет, Ubound вернет -1, в противном случае число больше -1. ​​

В исходном коде это скажет вам, является ли имя листа одним из имен, которые вы хотите опустить. Затем вам нужно будет проверить, скрыт ли этот лист отдельно.

if ubound(filter(arrsheets,"sheetNameOne"))=-1 then ' the sheet is not in the list
   if sheets("sheetNameOne").Visible = xlSheetHidden Then ' is it hidden?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...