Выборочное отображение листов пользователям

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

Классический способ определения имени заключается в использовании очевидного свойства UserName объекта Application:

	Sub Hello_1() MsgBox "Привет, " & Application.UserName End Sub

Выполнение такого макроса приведет к появлению простого окна сообщения с приветствием:

username1.png

Неплохо, несложно, но есть одно "но". В качестве UserName макрос берет имя пользователя, которое введено в поле Пользователь в параметрах Excel Файл - Параметры - Пользователь (File - Options - User):

username2.png

Засада в том, что это имя любой пользователь у себя на компьютере может в любой момент свободно поменять на любое другое. А у корпоративных пользователей там, зачастую, при установке Office автоматически прописывается какой-нибудь безличный "user".

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

Чтобы считать его нам потребуется использовать малоизвестную функцию VBA Environ, которая выдает информацию о различных параметрах операционной системы и Office на текущем компьютере. Аргумент USERNAME заставит эту функцию считать логин пользователя в Windows, под котороым сейчас произведен вход в компьютер:

	Sub Hello_1() MsgBox "Привет, " & Environ("USERNAME") End Sub

Таким образом, несложно организовать с помощью простого макроса, своего рода защиту при открытии файла - если книгу открывает не тот человек, то ему не показываются определенные листы с приватной информацией или промежуточными вычислениями. Если открыть редактор Visual Basic (Alt+F11) и затем двойным щелчком открыть в левом верхнем углу модуль ЭтаКнига (ThisWorkbook), то туда можно вставить макрос обработки события открытия книги, который и будет выполнять эту функцию защиты:

	 
Private Sub Workbook_Open() 
  If Environ("USERNAME") <> "Nikolay" Then 'если логин пользователя не Nikolay  
     Worksheets("Лист1").Visible = False 'скрываем Лист1 
     Worksheets(3).Visible = xlVeryHidden 'делаем 3-й лист суперскрытым 
  Else 
      For i = 1 To Worksheets.Count 'в противном случае 
        Worksheets(i).Visible = True 'проходим в цикле по всем листам 
      Next i 'и делаем их видимыми 
  End If 
End Sub

Теперь все листы будут видны только пользователю с именем (логином) Nikolay, а для всех остальных из трех листов книги будет виден только второй. Простор для применения этой функции широкий - пользуйтесь ;)

Ссылки по теме

 



Николай, статья отличная.
Хочу дополнить ссылкой на свою - Каждому пользователю свой лист/диапазон

Вдруг кому пригодится. У меня немного иной подход применен. Имя пользователя не берется с учетной записи ПК, а выбирается из списка, определенного ответственным за файл человеком. Каждому пользователю определен свой пароль. Помимо листов можно разрешить изменять только указанные диапазоны, а так же разрешить видеть только определенные строки и столбцы.
01.07.2013 14:10:40
The_Prist, большое спасибо за листочек WARNING )))) довольно интересный способ запрета работы с файлом. Применил в одну из своих таблиц.
01.10.2013 00:14:41
Супер, спасибо за дополнение - очень в тему!
17.04.2014 07:45:35
Николай, здравствуйте! Скажите пожалуйста, можно ли добавить в этом же файле лист на котором бы фиксировались время имена просмотревших файл?
19.04.2014 09:35:10
Почему нет? Нужно будет добавить макрос-обработчик события открытия книги, который будет записывать имя пользователя и дату-время на специальный скрытый лист. И при выходе из книги - то же самое.
Буквально, вчераделали такое упражнение со слушателями на тренинге по макросам. Называлось "Черный Ящик" :)
30.05.2014 12:30:09
Подскажите пожалуйста как добавить больше одного пользователя?
15.07.2014 16:34:16
Добавить несколько блоков If - End If в макрос обработчик открытия книги.
19.08.2015 17:59:24
Николай, приветствую!
А куда именно добавлять блоки If - End If ?
Что-то у меня не выходит... :-(
Добавила следующим образом, но тогда у меня листы видят все:
Private Sub Workbook_Open()
    If Environ("USERNAME") <> "Nikolay" Then    'если логин пользователя не Nikolay
     Worksheets("Лист1").Visible = False     'скрываем Лист1
     Worksheets(3).Visible = xlVeryHidden    'делаем 3-й лист суперскрытым
    Else
     For i = 1 To Worksheets.Count        'в противном случае
      Worksheets(i).Visible = True     'проходим в цикле по всем листам
     Next i                   'и делаем их видимыми
    End If

   If Environ("USERNAME") <> "Olga" Then    'если логин пользователя не Olga
     Worksheets("Лист1").Visible = False     'скрываем Лист1
     Worksheets(3).Visible = xlVeryHidden    'делаем 3-й лист суперскрытым
    Else
     For i = 1 To Worksheets.Count        'в противном случае
      Worksheets(i).Visible = True     'проходим в цикле по всем листам
     Next i                   'и делаем их видимыми
    End If

End Sub

Попробовала перевернуть условия тогда у меня User Olga не видит нужные листы:
Private Sub Workbook_Open()
    If Environ("USERNAME") = "Nikolay" Then    'если логин пользователя не Nikolay
        For i = 1 To Worksheets.Count        'в противном случае
      Worksheets(i).Visible = True     'проходим в цикле по всем листам
     Next i                   'и делаем их видимыми     

    Else
      Worksheets("Лист1").Visible = False     'скрываем Лист1
        Worksheets(3).Visible = xlVeryHidden    'делаем 3-й лист суперскрытым   
    End If

   If Environ("USERNAME") = "Olga" Then    'если логин пользователя не Olga
        For i = 1 To Worksheets.Count        'в противном случае
      Worksheets(i).Visible = True     'проходим в цикле по всем листам
     Next i                   'и делаем их видимыми     

    Else
      Worksheets("Лист1").Visible = False     'скрываем Лист1
        Worksheets(3).Visible = xlVeryHidden    'делаем 3-й лист суперскрытым   
    End If

End Sub

Пробовала делать через OR  
If Environ("USERNAME") = "Olga" or Environ("USERNAME") = "Nikolay" Then

Та же фигня ...
15.07.2014 13:21:04
Здравствуйте, а подскажите, пожалуйста, как сделать, чтобы данное приветствие выскакивало сразу при открытии файла? Чтобы макрос запускался автоматически, а не после нажатия Alt+8?
15.07.2014 16:32:41
Добавит это приветствие в модуль ЭтаКнига в виде макроса-обработчика события открытия книги:
Private Sub Workbook_Open()
  MsgBox "Привет, "  & Environ("USERNAME")
End Sub
15.07.2014 16:48:04
Спасибо, Николай. Я так и думала, но решила переспросить, так как я только учусь :oops:
15.11.2014 15:48:13
Спасибо, очень полезно. Николай, будьте добры, подскажите, как будет выглядеть код для решения чуть более сложной задачи, а именно: существует книга, которая открывается множеством пользователей, учетные записи в windows которых созданы по маске Sail_ИМЯ ПОЛЬЗОВАТЕЛЯ и Number_ИМЯ ПОЛЬЗОВАТЕЛЯ. Задача сделать так, чтобы только пользователи, чьи учетки содержат в названии Sail и Number смогли открыть книгу, а пользователи с другой маской не смогли открыть книгу вовсе, даже если она попала к ним в руки :) (например, чтобы при открытии "чужими" пользователями выдавалось окно с ошибкой). Защита паролем не подойдет...
15.11.2014 17:19:28
Максим, макросом не поставить защиту на открытие книги - только на просмотр листов. Защита на открытие - это шифрование файла с паролем, но оно не привязывается к имени пользователя. У Microsoft есть специальная программа для реализации подобной защиты - Rights Management System, но она ставится на сервер и всем сотрудникам на компьютеры IT-службой.
15.11.2014 18:40:49
Спасибо за ответ, Николай! Думаю, тогда остановиться на скрытии листов по описанной Вами технологии. Есть ли способ не конкретную учетку прописывать, на основании чего Excel открывает/скрывает листы, а указать несколько масок учетных записей (конкретные учетные записи все прописать невозможно - они постоянно добавляются/удаляются)? Например, если в имени учетки содержится Sail или Number, то листы доступны для просмотра, иначе "veryHidden".
29.03.2015 02:14:52
Здравствуйте,подскажите пожалуйста, можно ли в Excel пользоваться одновременно нескольким пользователям на разных компьютерах, заходя в один и тот же файл под своим именем. Если да подскажите какой использовать для этого метод, чтоб каждый пользователь мог открыть только те листы которые для него предназначены, а другие пользователи при этом видели бы только свои листы в этом же файле ?:oops:
27.09.2017 10:12:05
В чистом виде такого в Excel еще нет :)
Одновременное редактирование более-менее нормально реализовано только в Excel 2016, причем в файлах, хранящихся в облаке (OneDrive). Но права для пользователей на разные листы и там нельзя ставить.

Так что вариант тут только один: давать разным пользователям разные файлы, а потом собирать их в одно место макросом или через Power Query.
Николай, спасибо за этот урок.
Я, возможно, что то неправильно понял, но скачав пример и поменяв в нем имя на свое, я столкнулся с тем, что если у человека отключены макросы в EXCEL, то он при открытии файла видит все листы.
Если потом он нажимает на кнопку активации макросов, то листы скрываются, но если это предупреждение закрыть (нажав крестик) то листы остаются видимыми.

Так и должно быть?
27.09.2017 10:09:14
Надо сначала скрыть все листы, потом сохранить книгу и отдать ее другому пользователю.
Тогда, если макросы не разрешены, то скрытые листы останутся скрытыми, а видимыми их может сделать только макрос (который пользователь вынужден будет разрешить).
27.02.2019 07:09:55
Добрый день а как давать двух пользователей

If Environ("USERNAME";) <> "Nikolay" Then 'если логин пользователя не Nikolay
Наверх