может ли oop решить и возникновение излишних операторов if? - PullRequest
1 голос
/ 21 апреля 2020

Я хочу отформатировать фигуру (Oval 1), используя значение ячейки «A1». Я хочу отформатировать следующую фигуру (Oval 2), используя значение ячейки «A2» и т. Д. Я могу сделать это с помощью повторного «Если "," Else if ", но я ищу способ достичь этого с помощью" for "l oop или каким-либо другим способом, чтобы уменьшить операторы if / else и сделать код проще, но все же эффективным.

Sub format_connector()
'
Application.ScreenUpdating = False

On Error Resume Next
ActiveSheet.Unprotect
ActiveSheet.Shapes.Range(Array("Oval 1")).Select

If Range("D5") = "GREEN" Then
    Call green
    ElseIf Range("D5") = "YELLOW" Then
        Call yellow
    ElseIf Range("D5") = "BLACK" Then
        Call black
    ElseIf Range("D5") = "BLACK/WHITE" Then
        Call black_white
    ElseIf Range("D5") = "RED" Then
        Call red
    ElseIf Range("D5") = "RED/WHITE" Then
        Call red_white
    ElseIf Range("D5") = "ORANGE" Then
        Call orange
    ElseIf Range("D5") = "ORANGE/WHITE" Then
        Call orange_white
    ElseIf Range("D5") = "BLUE" Then
        Call blue
    ElseIf Range("D5") = "BLUE/WHITE" Then
        Call blue_white
    ElseIf Range("D5") = "BROWN" Then
        Call brown
    ElseIf Range("D5") = "BROWN/WHITE" Then
        Call brown_white
    ElseIf Range("D5") = "VIOLET" Then
        Call violet
    ElseIf Range("D5") = "GRAY" Then
        Call gray
    ElseIf Range("D5") = "WHITE" Then
        Call white
    ElseIf Range("D5") = "WHITE/BLACK" Then
        Call white_black
    ElseIf Range("D5") = "WHITE/BLUE" Then
        Call white_blue
    ElseIf Range("D5") = "WHITE/BROWN" Then
        Call white_brown
    ElseIf Range("D5") = "408-4001-882" Then
        Call cavity_plug
    ElseIf Range("D5") = "408-4001-445" Then
        Call cavity_plug
    ElseIf Range("D5") = "408-4002-073" Then
        Call cavity_plug
    ElseIf Range("D5") = "408-4001-935" Then
        Call cavity_plug
    ElseIf Range("D5") = "BLANK" Then
        Call blank
End If

Ответы [ 3 ]

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

Поскольку каждое условие использует один и тот же левый операнд в сравнении, блок If...Else If...End If может быть выражен с помощью блока Select...Case...End Select, и это уже уменьшит некоторые повторения.

Private Function GetMacroName(ByVal source As Range) As String
    Select Case Range("D5")
        Case "YELLOW":
            GetMacroName = "yellow"
        Case "BLACK":
            GetMacroName = "black"
        Case "BLACK/WHITE"
            GetMacroName = "black_white"
        '...
        Case Else
            GetMacroName = "blank"
    End Select
End Function

И затем вы можете использовать Application.Run для вызова безпараметрической процедуры:

Application.Run GetMacroName(Range("D5"))

Вы можете использовать al oop для запуска этой инструкции для разных диапазонов:

Dim sheet As Worksheet
Set sheet = ActiveSheet '<~ sure of that?

Dim i As Long
For i = 1 To N '<~ N=number of iterations; presumably the number of oval shapes
    Dim oval As Shape

    On Error Resume Next '<~ manually handle non-existing shape #i
    Set oval = sheet.Shapes("Oval " & i)
    On Error GoTo 0

    If Not oval Is Nothing Then
        Application.Run GetMacroName(sheet.Range("D" & 5 + i - 1)), oval
    End If

    Set oval = Nothing
Next

В качестве альтернативы мы могли бы выполнить итерацию Shapes коллекция листа:

Dim sheet As Worksheet
Set sheet = ActiveSheet '<~ sure of that?

Dim oval As Shape, i As Long
For Each oval In sheet.Shapes
    i = i + 1
    If Left(oval.Name, 4) = "Oval" Then
        Application.Run GetMacroName(sheet.Range("D" & 5 + i)), oval
    End If
Next

Обратите внимание, что в обоих случаях макрос получает объект Shape, с которым он работает. Передавая параметры, вы делаете свой код менее зависимым от глобального состояния и более простым для отслеживания: вам не нужно выяснять, кто из вызывающих 3 создает кадр вызова, который в некоторой форме вызывает .Select, чтобы знать, что вы ' работает с! Передача параметров значительно упрощает отладку позже.

Public Sub Yellow(ByVal sh As Shape)
    sh.ForeColor = vbYellow
End Sub

Обратите внимание, что если это все, что здесь происходит, у вас должен быть только один макрос вместо:

Public Sub FormatOvalShape(ByVal oval As Shape, ByVal color As Long)
    oval.ForeColor = color
    '...
End Sub

.. и пусть звонящий параметризирует вызов - вы еще больше уменьшите дублирование кода. На самом деле, это избавило бы от необходимости отображать имена макросов; вместо этого мы отображаем цветовые коды:

Dim sheet As Worksheet
Set sheet = ActiveSheet '<~ sure of that?

Dim oval As Shape, i As Long
For Each oval In sheet.Shapes
    If Left(oval.Name, 4) = "Oval" Then
        FormatOvalShape oval, GetColorCode(sheet.Range("D" & 5 + i))
    End If
    i = i + 1
Next
0 голосов
/ 23 апреля 2020

Sub FormatConnector ()

Application.ScreenUpdating = False On Error Resume. Следующее подчеркивание вызова 'преобразуется в подчеркивание между цветами

Тусклый цвет в виде строки

ActiveSheet.Shapes. Range (Array ("Oval 1")). Выберите цвет = Range ("D5"). Вызов значения CAVITY_PLUG End If Application.Run color

ActiveSheet.Shapes.Range (Array ("Oval 2")) .Выберите

color = Range ("D6"). Значение Application.Run color

ActiveSheet.Shapes.Range (Array ("Oval 3")). Выберите

color = Range ("D7"). Значение Application.Run color

0 голосов
/ 21 апреля 2020

Как насчет этого решения?

Sub format_connector()
    ' 008 26 Apr 2020

    Dim Ws As Worksheet
    Dim SubName As String
    Dim R As Long
    Dim i As Integer

    Set Ws = ActiveSheet                        ' Be safe! Call the sheet by name.
    On Error Resume Next
    Ws.Unprotect
    On Error GoTo 0

    Application.ScreenUpdating = False
    R = 5                                       ' start the loop at D5
    Do
        SubName = Replace(Ws.Cells(R, "D").Value, "/", "_")
        If SubName = "" Then Exit Do
        R = R + 1

        i = i + 1
        Ws.Shapes("Oval " & i).Select
        If Val(SubName) Then SubName = "cavity_plug"
        Application.Run SubName
    Loop
    Application.ScreenUpdating = True
End Sub

Приведенный выше код был изменен для выбора овалов 1, 2 и c. для всех параметров, указанных в столбце D, начиная с D5.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...