В данной статье хочу описать вкратце способ, как можно запустить какой-то файл Excel с разрешенными макросами. Зачем это надо: бывают ситуации, когда Вы высылаете файл с макросами и хотите, чтобы его открывали только с разрешенными макросами, т.к. без них он бесполезен (как правило через макросы выполняются некие операции при работе с файлом). В принципе есть способы заставить пользователя работать с файлом только при включенных макросах. Самый простой (способ 1) - это заставить его именно разрешить их выполнение, прежде чем начать работу с файлом.
Самый простой и легко исполняемый способ. Создаете в нужной книге новый лист. Называете его "WARNING". На листе мы пишем инструкцию по действиям пользователя для включения макросов. Что-то типа:
Excel 2003: Сервис- Безопасность- Уровень макросов «Низкий»
Excel 2007: Меню- Параметры Excel- Центр управления безопасностью- Параметры центра управления безопасностью- Параметры макросов- Разрешить все макросы;
Excel 2010: Файл- Параметры- Центр управления безопасностью- Параметры центра управления безопасностью- Параметры макросов- Разрешить все макросы.
И скрываем все листы в книге, кроме листа "WARNING". Теперь в остается дело за малым: в модуль книги вставляете следующий код:
'Данная процедура скрывает перед закрытием книги все листы, 'кроме листа "WARNING" Private Sub Workbook_BeforeClose(Cancel As Boolean) Application.ScreenUpdating = False Dim wsSh As Worksheet Sheets("WARNING").Visible = -1 For Each wsSh In ThisWorkbook.Sheets If wsSh.Name <> "WARNING" Then wsSh.Visible = 2 Next wsSh ThisWorkbook.Save End Sub 'Данная процедура показывает перед открытием книги все листы, 'кроме листа "WARNING" Private Sub Workbook_Open() Dim wsSh As Worksheet For Each wsSh In ThisWorkbook.Sheets wsSh.Visible = -1 Next wsSh ThisWorkbook.Sheets("WARNING").Visible = 2 End Sub |
Из кода видно, что если макросы будут отключены, то код Workbook_Open не будет выполнен. Следовательно пользователь увидит только лист "WARNING", на котором у нас написаны инструкции по включению макросов, которые ему в любом случае придется выполнить, если есть желание работать с файлом.
Этот способ подразумевает создание отдельного файла, который будет запускать файл Excel. Я предоставлю на выбор либо скрипт VBS, либо созданный мной файл EXE. В чем прелесть. При использовании данного способа совершенно неважно запущен ли уже у пользователя Excel или нет, разрешены ли макросы. Скрипт или EXE сам все запустит и разрешит.
Что такое скрипт VBS? Это обычный текстовый файл, сохраненный с расширением VBS. Такой файл распознается операционной системой как исполняемый и код, расположенный в нем, запускается при двойном щелчке на файле.
Чтобы создать такой файл необходимо:
- создать обычный текстовый файл
- открыть его
- записать в него текст:
test Sub test() Dim objXL Dim Secur Set objXL = CreateObject("Excel.Application") objXL.Visible = TRUE secur = objXL.AutomationSecurity objXL.AutomationSecurity = 1 objXL.Workbooks.Open replace(Wscript.ScriptFullName,".vbs",".xls"),,,,"4321" objXL.AutomationSecurity = secur End Sub
- сохранить изменения
- поменять расширение текстового файла с .txt на .vbs.
Если не отображается расширение:
Панель управления-Свойства папки(для Win 7 - Параметры папок)- вкладка Вид- Снять галочку с "Скрывать расширение для зарегистрированных типов файлов"
Скрипт запускает файл Excel, имя которого совпадает с именем скрипта и расположенного в той же папке. В примере к статье это файл "Test". Таким образом Вы можете давать любое имя файлу Excel и файлу скрипта, лишь бы они совпадали. Т.е. назвав скрипт "Run", Вы должны будете и файл Excel назвать так же - "Run". В приведенном коде так же есть возможность указать пароль для открытия файла(в тексте скрипта это пароль 4321, но установить можно любой через свойства файла). Как установить пароль я описывал в этой статье: Как удалить книгу из самой себя. Пароль как правило устанавливается для того, чтобы при попытке запустить файл Excel без скрипта был запрошен пароль. Т.е. без скрипта файлом не воспользоваться. Есть и ложка дегтя - после открытия файла пароль может удалить любой, кто его открыл.
Плюсы использования скрипта:
- пользователь совершает минимум действий
- макросы разрешены как ни крутись
Минусы:
- необходимость создания отдельного файла и привязка к имени
- возможность подсмотреть пароль к файлу, просто сменив расширение файла-скрипта на .txt
- возможность сменить/снять пароль к файлу после его открытия скриптом(можно избежать, внеся некоторый код в файл. Например сохранять только с нужным паролем). В примере пароль к файлу: 4321
Файл EXE. Долго пояснять не буду. Основные моменты все те же, что и со скриптом, т.к. в принципе это одно и то же, за исключением того, что код файла EXE нельзя подсмотреть, просто сменив расширение. А это значит, что и пароль к файлу подсмотреть тоже не получится(без использования специальных навыков и программ). Создается такой файл в специальной программной среде: С++, VisualBasic, Delphi и т.п.
В примере вы найдете файлы с примерами реализации всеми описанными способами:
Run_Wit_Macro.zip (28,1 КиБ, 4 099 скачиваний)
Также см.:
Почему не работает макрос?
Управление безопасностью макросов
Что-то не получается первый вариант. Офис 2007
Скрываю листы, кроме WARNING - при открытии все видны.
Пробую в примере, скачиваю. Моргает полсекунды красное WARNING и видно только Лист 2 с кнопкой "Нажми меня". Жму , всплывает надпись - реклама сайта" и все.
Не совсем понятно, а что Вы хотели видеть в примере? Там всего два листа - WARNING и лист с кнопкой. Если макросы разрешены - показывается только лист с кнопкой. Кнопка исключительно для того, чтобы продемонстрировать, что макросы работают. При нажатии на кнопку просто показывается MsgBox, вызванный кодом в этом файле.
А почему у Вас не получается в своем файле - возможно, листы создали, но макросы в модуль ЭтаКнига перенести забыли.
Ура заработало!
Я тут пока мудрил, включил полностью все макросы в Параметры Excel. Поэтому WARNING и не появлялась, так как макросы уже были разрешены.
Сейчас все именно так, как надо, чтобы файл передавать людям и они не забывали включать макросы, спасибо!
Добрый день. Воспользовался первым способом, встроил в него макрос для закрытия файла по таймеру. Все работает, вот только если макрос по истечению времени сам закрывает файл, то при следующем открытии файла лист с инструкцией по включению макросов не появляется и возможно работать в файле без включения макросов, а следовательно и макрос на отключение по таймеру работать не будет. Он появляется снова только при разовом включении макросов самостоятельно, а потом снова все работает, до закрытия файла макросом.
Код для книги:
'Данная процедура скрывает перед закрытием книги все листы,
'кроме листа "Внимание"
Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ScreenUpdating = False
Dim wsSh As Worksheet
Sheets("Внимание").Visible = -1
For Each wsSh In ThisWorkbook.Sheets
If wsSh.Name "Внимание" Then wsSh.Visible = 2
Next wsSh
ThisWorkbook.Save
End Sub
'Данная процедура показывает перед открытием книги все листы,
'кроме листа "Внимание"
Sub Workbook_Open()
Dim wsSh As Worksheet
For Each wsSh In ThisWorkbook.Sheets
wsSh.Visible = -1
Next wsSh
ThisWorkbook.Sheets("Внимание").Visible = 2
Application.OnTime Now + TimeValue("00:01:00"), "CloseBook"
End Sub
Код для модуля:
Public iTimer As Date
Private Sub CloseBook()
ThisWorkbook.Close (True)
End Sub
Подскажите, пожалуйста, что нужно поменять, чтобы сообщение о включении макросов выходило всегда при открытии файла и не важно было закрыл ли его макрос или человек вручную.
Вам надо в Вашу процедуру CloseBook добавить код из процедуры Workbook_BeforeClose, перед строкой ThisWorkbook.Close (True)
Огромное спасибо, все работает
Добрый день.
А можно попросить исходник для exe-шника, чтоб поправить - потому что мой файл имеет расширение xlsm а не xls
Евегений, код практически тот же, что и для скрипта VBS, если использовать тот же VB6. Но что он Вам даст? У Вас есть компилятор VB6, чтобы пересобрать исходный код в EXE исполняемый файл? Если есть - то и код можете взять тот же что в VBS, поменяв пару моментов(не должно быть сложно, если Вы хоть немного в теме). А если компилятора нет - какой смысл в исходном коде?
Да думал, поделфить :) вспомнить как экзехи писать.. Ну да ладно.. Спасибо за статью оч помогла.
А еще момент, можно? Как в vbs скриптике указать, чтоб окно эксельки открывалось на весь экран?
Евегений, для Delphi точно не подскажу - я на нем не пишу.
А по поводу окна - так там вообще нет проблем, так же как и в VBA(только объект добавляем):
objXL.ActiveWindow.WindowState = -4137'xlMaximized
спасибо за помощь
Дмитрий, добрый день.
Наблюдается такая особенность. Подскажите как правильно ее обойти?
Когда запускается файл через vbs - то для другого пользователя одновременно пытающегося открыть файл - не выпадает сообщение, что файл занят другим пользователем данный файл доступен только для чтения..
Если же открываешь непосредственно файл xlsm - сообщение выдается!
Евгений, три раза перечитал вопрос, но так и не понял: а что конкретно надо-то? Чтобы сообщение появлялось в любом случае или наоборот? В принципе, и в том и в другом случае это не так просто. Если надо показывать сообщение, то сначала придется определить доступность файла из VBS(например, как написано в этой статье: , смотреть ближе к концу статьи). А во втором случае вообще нет других путей, как обрабатывать открытие каждого файла из надстройки.