В данной статье хочу описать вкратце способ, как можно запустить какой-то файл 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 148 скачиваний)
Также см.:
Почему не работает макрос?
Управление безопасностью макросов
Что-то не получается первый вариант. Офис 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(например, как написано в этой статье: , смотреть ближе к концу статьи). А во втором случае вообще нет других путей, как обрабатывать открытие каждого файла из надстройки.
Добрый день.
При использовании макроса столкнулся со следующей проблемой:
Книга с макросом, подготовленная к заполнению, расположена на сетевом ресурсе, доступ к записи которого для меня закрыт, поэтому при закрытии файла файла появляется соответствующее окно с ошибкой '1004' и другие предупреждающие сообщения.
Как сделать, чтобы при закрытии книги, находящейся на сетевом ресурсе с закрытым доступом к сохранению, не всплывало несколько окон? Но при этом не должна пропадать возможность сохранения книги при нажатии на "Сохранить" или "Сохранить как".
Без понимания как минимум того, какой метод из описанных в статье используете - никак.
Использую этот метод:
'Данная процедура скрывает перед закрытием книги все листы,
'кроме листа "Начало"
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'Снятие защиты книги
ThisWorkbook.Unprotect sPWD
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.Protect sPWD
Application.ScreenUpdating = True
Application.StatusBar = False
ThisWorkbook.Save 'сохранение перед закрытием
End Sub
А вот эта строка на мысли не наводит?
ThisWorkbook.Save 'сохранение перед закрытием
как думаете, что она делает? :) И что будет, если пытаться выполнить её для книги, к которой нет доступа на сохранение? Уберите строку. Правда, в этом случае, код потеряет свою основную суть - скрытие лишних листов при закрытии(при условии, что книга была сохранена при использовании).
Можете сделать и более кардинально - оставить возможность сохранения книги в случае, когда это разрешено расположением файла и пропуск ошибки сохранения, если это запрещено. Замените приведенную выше строку на такие:
Кстати, не совсем понял, что за другие предупреждающие сообщения(что в них пишется, когда появляются и т.п.). Поэтому с ними уж сами как-нибудь.
И уже тем более не понимаю, как Вы себе представляете "возможность сохранения книги при нажатии на "Сохранить"", если доступа к сохранению книги нет. Сохранить как - да, можете использовать - код этому никак не препятствует, если сохранение в указанное расположение разрешено.
"Кстати, не совсем понял, что за другие предупреждающие сообщения(что в них пишется, когда появляются и т.п.)"
По умолчанию отключен буфер обмена, поэтому при открытии книги об этом появляется информация.
"И уже тем более не понимаю, как Вы себе представляете "возможность сохранения книги при нажатии на "Сохранить"", если доступа к сохранению книги нет."
Чтобы не перестало появляться предупреждающее окно о доступности только для чтения и предоставлением возможности сохранения в доступном месте.
"Можете сделать и более кардинально - оставить возможность сохранения книги в случае, когда это разрешено расположением файла и пропуск ошибки сохранения, если это запрещено. Замените приведенную выше строку на такие:
"
Вот это мне и нужно. Буду пробовать. Спасибо.