Проверка существования листов и скрытие / скрытие на основе значений ячеек - PullRequest
0 голосов
/ 14 ноября 2018

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

. Общее ожидание состоит в том, что если у пользователя есть 1 в ячейке под листом, толист виден, в противном случае лист должен быть очень скрыт

Этот код находится в модуле 1, хотя не уверен, что он должен быть на уровне рабочей книги.

Я объявляю следующее вне функций, чтобы они могли быть вызваны внутри каждой из них:

Dim lRow As Long, wsStatus As Boolean, shtloc As Integer

Тогда это моя основная функция (которая может быть подпрограммой на уровне рабочей книги, не уверен)

    Function CheckSheetPermission()

Sheet9.Visible = xlSheetVisible
For Each ws In ActiveWorkbook.Worksheets
    If ws.Name <> "Welcome" Then ws.Visible = xlSheetVeryHidden
Next ws
Sheet12.Visible = xlSheetVisible
Sheet12.Activate
With ActiveSheet
Dim sht As Worksheet
Call GetRowNum(Range("A3:A200"), LCase(Environ("UserName")))
    For Each Cell In Range("B" & lRow & ":GS" & lRow)
    If Abs(Cell.Value) = "1" Then
        shtloc = Cell(2, ActiveCell.Column).Value
        Call wsExists(Sheets(shtloc))
        If wsStatus = False Then
            Sheets(shtloc).Visible = xlSheetVisible
        End If
    Else
        shtloc = Cell(2, ActiveCell.Column).Value
         Call wsExists(Sheets(shtloc))
        If wsStatus = False Then
            Sheets(shtloc).Visible = xlSheetVeryHidden
        End If
    End If
    Next
End With
End Function

Это выглядит на листе ниже, изначально он предназначен для того, чтобы убедиться, что приветствие и лист 1 временно видны до тех пор, пока не выполнится код, который затем устанавливает правильную видимость для всех листов (я предполагаю, чтолист должен быть виден для кода для чтения ячеек)

изображение листа

Получить номер строки просто ищетпользователь и получает номер строки

Call GetRowNum(Range("A3:A200"), LCase(Environ("UserName")))

И этот код функции

Function GetRowNum(rng As Range, user As String)


    On Error Resume Next
    lRow = Application.WorksheetFunction.Match(user, rng, 0) + 2
    On Error GoTo 0


End Function

В настоящее время кажется, что он работает неправильно, когда я вызываю следующую функцию;

Call wsExists(Sheets(shtloc))

Я получаю индекс из-за ошибки диапазона.Это может произойти из-за того, что переменная не установлена ​​должным образом, или из-за самой функции, которую я вызываю, но я не уверен, где лучше всего начинать вносить поправки в код и проверять результаты для дальнейшей изоляции проблемы

Ограниченная обработка ошибок на данном этапекак пытаясь отловить ошибки.если я добавлю обработку ошибок в основную функцию, она просто проходит, и никакие листы не являются скрытыми или видимыми, кроме тех, которые установлены в начале (контроль листов и приветствие)

Function wsExists(wsSheet As Worksheet)
On Error Resume Next
On Error GoTo 0
If Not wsSheet Is Nothing Then
wsStatus = "True"
Else
wsStatus = "False"
End If

End Function

Пожалуйста, дайте мне знать, если вам нужно большеИнформация.

Я просто пытаюсь выполнить следующие шаги:

  1. Проверить, какие листы должны быть видны пользователю, открывающему файл через цикл
  2. Проходкаждый из номеров листов, если они существуют, с использованием переменной номера листа вместе со значением 0/1 под строкой рядом с именем пользователя и настройкой видимости листа (1 = разрешено.0 = не разрешено)

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

### EDIT

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

Thisworkbook

Private Sub Workbook_Open()

Dim ws As Worksheet
Dim shtloc As String
Dim c As Long
Dim lRow2 As Long
Sheet9.Visible = xlSheetVisible

For Each ws In ActiveWorkbook.Worksheets
    If ws.Name <> "Welcome" Then ws.Visible = xlSheetVeryHidden
Next ws
Sheet12.Visible = xlSheetVisible
Sheet12.Activate
With Sheet12
    lRow2 = Module2.lRow2(Range("A3:A5"), LCase(Environ("UserName")))


        For c = 2 To ActiveWorkbook.Worksheets.Count + 1
        shtloc = Cells(1, c).Value2
             With Cells(lRow2, c)
             perm = Cells(lRow2, c).Value2
                Select Case perm
                    Case ("V")
                    'Visible
                        Sheets(shtloc).Visible = xlSheetVisible
                    Case ("P")
                    'visible protected
                        Sheets(shtloc).Visible = xlSheetVeryHidden
                        Sheets(shtloc).Protect Password:="*********"
                    Case ("D")
                    'Access denied
                        Sheets(shtloc).Visible = xlSheetVeryHidden
                    End Select
             End With
        Next c

End With

End Sub

Модуль

Function lRow2(rng As Range, user As String)

    On Error Resume Next
    With ActiveSheet
    lRow2 = Application.WorksheetFunction.Match(user, rng, 0)

    lRow2 = lRow2 + 2

    End With
End Function

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

1 Ответ

0 голосов
/ 14 ноября 2018

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

For Each Cell In Range("B" & lRow & ":GS" & lRow)

я бы использовал

For Each currentCell In Range("B" & lRow & ":GS" & lRow)

Это позволило бы избежать первой отмеченной мной ошибки:

shtloc = Cell(2, ActiveCell.Column).Value

Эта строка не будет возвращать то, что вы хотите,Во-первых, вам нужно «s» в конце «Cell».Во-вторых, имена ваших листов находятся в строке 1, в-третьих, в вашем коде неясно, какая ячейка активирована в настоящий момент, это может привести к странному поведению.Вместо этого попробуйте заменить его на:

shtloc = Cells(1, currentCell.Column).Value

Теперь ваша основная ошибка заключается в том, что вы пытаетесь проверить, существует ли лист, вызывая ошибку.Это приводит к вашей ошибке вне диапазона.

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

https://stackoverflow.com/a/6040454/10645669

Function sheetExists(sheetToFind As String) As Boolean sheetExists = False For Each sheet In Worksheets If sheetToFind = sheet.name Then sheetExists = True Exit Function End If Next sheet End Function


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

Function wsExists(wsSheet As Worksheet)
On Error Resume Next
On Error GoTo 0
If Not wsSheet Is Nothing Then
wsStatus = "True"
Else
wsStatus = "False"
End If

End Function

Может быть написано:

Function wsExists(wsSheet As Worksheet) as boolean
On Error Resume Next
On Error GoTo 0
If Not wsSheet Is Nothing Then
wsExists = "True"
Else
wsExists = "False"
End If

End Function

Это позволяет вам использовать функцию непосредственно в вашем коде, например:

If wsExists(Sheets(shtloc)) = False Then

Больше нет глобальныхпеременная, и больше не использовать ключевое слово call.

Кроме того, как правило, если написанный код ничего не возвращает, то он должен быть "sub".Они могут быть вызваны без вызова ключевого слова, просто указав аргументы без скобок.Пример:

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