Интеграция нескольких кодов в один рабочий лист - PullRequest
1 голос
/ 27 мая 2019

Я пытаюсь реализовать несколько функций в одной рабочей таблице_обмен. Мне уже удалось интегрировать 3 функции (все они относятся к скрытию / скрытию строк), однако у меня возникли проблемы с добавлением функции, которая позволяет выбирать несколько элементов в раскрывающемся списке.

Я попытался добавить новый код множественного выбора в ранее существующий код, и он не дает мне ошибок, однако он не запустится. В идеальном мире он сохранял бы функции скрытия / скрытия, а также допускал множественный выбор в идентифицированных строках.

Private Sub Worksheet_Change(ByVal Target As Range)

ActiveSheet.Activate

If Not Application.Intersect(Range("C10:AA10"), Range(Target.Address)) 

Is Nothing Then
    Select Case Target.Value

    Case Is = "Select One": Rows("14:58").EntireRow.Hidden = True
                         Rows("10").EntireRow.Hidden = False
    Case Is = "1": Rows("17:58").EntireRow.Hidden = True
                        Rows("14:16").EntireRow.Hidden = False
    Case Is = "2":  Rows("20:58").EntireRow.Hidden = True
                        Rows("14:19").EntireRow.Hidden = False
    Case Is = "3": Rows("23:58").EntireRow.Hidden = True
                        Rows("14:22").EntireRow.Hidden = False
    Case Is = "4":  Rows("26:58").EntireRow.Hidden = True
                        Rows("14:25").EntireRow.Hidden = False
    Case Is = "5": Rows("29:58").EntireRow.Hidden = True
                        Rows("14:28").EntireRow.Hidden = False
    Case Is = "6":  Rows("32:58").EntireRow.Hidden = True
                        Rows("14:31").EntireRow.Hidden = False
    Case Is = "7": Rows("35:58").EntireRow.Hidden = True
                        Rows("14:34").EntireRow.Hidden = False
    Case Is = "8":  Rows("38:58").EntireRow.Hidden = True
                        Rows("14:37").EntireRow.Hidden = False
    Case Is = "9": Rows("41:58").EntireRow.Hidden = True
                        Rows("14:40").EntireRow.Hidden = False
    Case Is = "10":  Rows("44:58").EntireRow.Hidden = True
                        Rows("14:43").EntireRow.Hidden = False
    Case Is = "11": Rows("47:58").EntireRow.Hidden = True
                        Rows("14:46").EntireRow.Hidden = False
    Case Is = "12":  Rows("50:58").EntireRow.Hidden = True
                        Rows("14:49").EntireRow.Hidden = False
    Case Is = "13": Rows("30:58").EntireRow.Hidden = True
                        Rows("14:52").EntireRow.Hidden = False
    Case Is = "14":  Rows("56:58").EntireRow.Hidden = True
                        Rows("14:55").EntireRow.Hidden = False
    Case Is = "15":  Rows("14:58").EntireRow.Hidden = False
End Select
End If
If Not Intersect(Range("C66:AA66"), Target) Is Nothing Then
    Select Case Target.Value
    Case "GBP", "USD", "Yuan", "EUR", "LRD", "Select One"
        Rows("67").Hidden = True
    Case "Other"
        Rows("67").Hidden = False

    End Select
End If
If Not Intersect(Range("C11:AA11"), Target) Is Nothing Then
    Select Case Target.Value
    Case "$"
        Rows("13").Hidden = True
        Rows("12").Hidden = False
    Case "%"
        Rows("13").Hidden = False
        Rows("12").Hidden = True
    Case "Select One"
        Rows("13").Hidden = True
        Rows("12").Hidden = True

    End Select
End If
Dim Oldvalue As String
Dim Newvalue As String
Application.EnableEvents = True
On Error GoTo Exitsub
If Target.Row = "15",”18”,”21” Then
  If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
  Else: If Target.Value = "" Then GoTo Exitsub Else
    Application.EnableEvents = False
    Newvalue = Target.Value
    Application.Undo
    Oldvalue = Target.Value
      If Oldvalue = "" Then
        Target.Value = Newvalue
      Else
        If InStr(1, Oldvalue, Newvalue) = 0 Then
            Target.Value = Oldvalue & ", " & Newvalue
      Else:
        Target.Value = Oldvalue
      End If
    End If
  End If
End If
 Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True

End Sub

Я хочу, чтобы это позволило продолжать скрывать / показывать заданные строки на основе выбранных элементов, а также разрешать множественный выбор из раскрывающихся списков в строках, обозначенных в коде. Код не дает мне ошибок, но множественный выбор не запускается

1 Ответ

1 голос
/ 28 мая 2019

Мне кажется, я понимаю, что вы пытаетесь сделать, и надеюсь, что эти замечания помогут вашему коду.Итак, несколько комментариев ...

  1. Всегда используйте Option Explicit.Независимо от того, какой пример кода вы найдете в Интернете, использование этой привычки в будущем вам очень поможет.
  2. Это БОЛЬШАЯ помощь в использовании промежуточных переменных в вашем коде, которая делает код самодокументируемым.При назначении промежуточных значений и объектов штраф не взимается, поэтому используйте это в своих интересах.
  3. Разделите логические блоки на отдельные подпрограммы или функции.Это делает ваш код «функционально изолированным» - это означает, что каждый блок кода имеет определенный фокус, и если вам нужно изменить его, вы изменяете его только в одном месте.Это также облегчает чтение вашего кода без прокрутки вверх и вниз, чтобы получить представление о общей логике.

В случае вашего Worksheet_Change кода события я могу уменьшить логику долегче понять поток:

Option Explicit

Private Sub Worksheet_Change(ByVal target As Range)
    Dim groupsRange As Range
    Dim currencyRange As Range
    Dim valuesRange As Range
    Set groupsRange = ActiveSheet.Range("C10:AA10")
    Set currencyRange = ActiveSheet.Range("C66:AA66")
    Set valuesRange = ActiveSheet.Range("C11:AA11")

    If Not Intersect(groupsRange, target) Is Nothing Then
        ShowActiveGroups target
    ElseIf Not Intersect(currencyRange, target) Is Nothing Then
        ShowCurrency target
    ElseIf Not Intersect(valuesRange, target) Is Nothing Then
        ShowValues target
    End If

    If target.Count > 1 Then Exit Sub

    If (target.Row = 15) Or (target.Row = 18) Or (target.Row = 21) Then
        CheckMultiSelect target
    End If
End Sub

Ясно, что я, возможно, не получаю «точку» ваших диапазонов (используя «группы», «валюта», «значения»), но вы должны использовать описательныйимена, которые облегчают понимание ЧТО и ПОЧЕМУ логика работает в определенных разделах.

Код для Subs, вызываемый в событии Worksheet_Change, помещается в отдельный модуль и всеони помечены как Public.У каждого из них сходная логика, и здесь есть несколько вещей, которые работают.

В каждом из логических блоков (т. Е. В коде Sub в данном случае) вы должны выполнить шаги, чтобы точно установить , на какой лист ссылается.Очень важно всегда полностью квалифицировать ссылки на диапазон (см. # 5) .Самый простой способ сделать это (без очень длинных составных операторов) - использовать промежуточные переменные.

Таким образом, в каждой из вышеперечисленных подпрограмм «Show» я устанавливаю ссылку на Worksheet целевой ячейки (ячейки, которая вызвала событие Worksheet_Change).

Dim targetWS As Worksheet
Set targetWS = target.Parent
Попробуйте определить константы для, казалось бы, «случайных» чисел или значений, которые не имеют реального значения вне контекста вашей рабочей таблицы.

В вашем случае вы ссылаетесь на множество разных строк и скрываете / скрываете их.Понятия не имею почему.Но если бы вы могли «назвать» строки в вашем коде, это могло бы иметь больше смысла.Вот несколько примеров, которые я использовал:

Const RED_GROUP_1 As String = "14:58"
Const RED_GROUP_2 As String = "10"
Const GREEN_GROUP_1 As String = "17:58"
Const GREEN_GROUP_2 As String = "14:16"

Итак, первые три подпрограммы «Показать» могут выглядеть примерно так:

Public Sub ShowActiveGroups(ByRef target As Range)
    Dim targetWS As Worksheet
    Set targetWS = target.Parent

    Const RED_GROUP_1 As String = "14:58"
    Const RED_GROUP_2 As String = "10"
    Const GREEN_GROUP_1 As String = "17:58"
    Const GREEN_GROUP_2 As String = "14:16"

    With targetWS
        Select Case target.Value
            Case "Select One"
                .Rows(RED_GROUP_1).EntireRow.Hidden = True
                .Rows(RED_GROUP_2).EntireRow.Hidden = False
            Case 1
                .Rows(GREEN_GROUP_1).EntireRow.Hidden = True
                .Rows(GREEN_GROUP_2).EntireRow.Hidden = False
            Case 2
                .Rows("20:58").EntireRow.Hidden = True
                .Rows("14:19").EntireRow.Hidden = False

            ' ...

            Case Else
                '--- what should we do if it's not a valid value?
        End Select
    End With
End Sub

Public Sub ShowCurrency(ByRef target As Range)
    Dim targetWS As Worksheet
    Set targetWS = target.Parent

    Const CURRENCY_LINE As String = "67"

    With targetWS
        Select Case target.Value
            Case "GBP", "USD", "Yuan", "EUR", "LRD", "Select One"
                .Rows(CURRENCY_LINE).EntireRow.Hidden = True
            Case "Other"
                .Rows(CURRENCY_LINE).EntireRow.Hidden = False
            Case Else
                '--- what should we do if it's not a valid value?
        End Select
    End With
End Sub

Public Sub ShowValues(ByRef target As Range)
    Dim targetWS As Worksheet
    Set targetWS = target.Parent

    Const MONEY_LINE As String = "13"
    Const PERCENT_LINE As String = "12"

    With targetWS
        Select Case target.Value
            Case "$"
                .Rows(MONEY_LINE).EntireRow.Hidden = True
                .Rows(PERCENT_LINE).EntireRow.Hidden = False
            Case "%"
                .Rows(MONEY_LINE).EntireRow.Hidden = False
                .Rows(PERCENT_LINE).EntireRow.Hidden = True
            Case "Select One"
                .Rows(MONEY_LINE).EntireRow.Hidden = True
                .Rows(PERCENT_LINE).EntireRow.Hidden = True
            Case Else
                '--- what should we do if it's not a valid value?
        End Select
    End With
End Sub

Наконец, у меня всегда были проблемы с проверкой данных/ multi-select код, который вы нашли в webz .Так что я вбрасываю тот, который я использую, у которого есть пара легких модов.Этот код также входит в модуль обычного кода.

Public Sub CheckMultiSelect(ByRef target As Range)
    Dim targetWS As Worksheet
    Set targetWS = target.Parent

    On Error Resume Next
    Dim dvCheck As Range
    Set dvCheck = targetWS.Cells.SpecialCells(xlCellTypeAllValidation)
    If dvCheck Is Nothing Then Exit Sub

    Application.EnableEvents = False
    '--- only allow multi-select if the cell has defined data validation
    If Not Intersect(dvCheck, target) Is Nothing Then
        Dim currentValue As String
        Dim oldValue As String
        currentValue = target.Value
        Application.Undo
        oldValue = target.Value
        If oldValue = vbNullString Then
            target.Value = currentValue
        Else
            If InStr(1, oldValue, currentValue) = 0 Then
                target.Value = oldValue & "," & currentValue
            Else
                If currentValue = vbNullString Then
                    target.Value = vbNullString
                Else
                    target.Value = oldValue
                End If
            End If
        End If
    End If
    Application.EnableEvents = True
End Sub

Используя приведенный выше код как в модуле рабочего листа, так и в модуле обычного кода, я успешно смог выполнить некоторые операции в вашем исходном вопросе.

...