Мяв! Имеется код, выполняющий определенную обработку группы файлов в папке. По каким-то причинам этот код работает не стабильно, и может в любой момент выдать ошибку. Причем, после нажатия F5 он совершенно спокойно продолжает работать. Проблема в том, что сей код расположен в надстройке, проект которой закрыт паролем (обычным, без ухищрений). Запуск кода выполняет VBS скрипт. Ручками снимать пароль с надстройки перед запуском, и вновь ставить, как-то грустно. Тут есть фраза
Цитата
Я лично знаю два способа снять пароль программно: через метод SendKeys и использовании функций API. Т.к. второй способ довольно громоздкий и сложный для понимания - я в данной статье опишу лишь первый способ.
Но, применять глючный метод для лечения глючного кода, это только плодить глюки, а найти решение через API, к сожалению, не удалось. Люди добрые, поможите, чем можите..
Здравствуйте, Андрей! Попробуйте следующий код - меня он не подводил.
Код
' Снимает защиту проекта.
' Идея: http://www.rondebruin.nl/
Function UnprotectVBProject(ByVal wb As Workbook, ByVal Password As String) As Boolean
Dim vbProj As Object, vbCtl As Object
Set vbProj = wb.VBProject
UnprotectVBProject = False
If vbProj.Protection <> 1 Then
UnprotectVBProject = True
Exit Function
End If
Set Application.VBE.ActiveVBProject = vbProj
DoEvents2
If Application.VBE.ActiveVBProject.Name <> vbProj.Name Then
Exit Function
End If
Set vbCtl = Application.VBE.CommandBars(1).FindControl(ID:=2578, recursive:=True)
With vbCtl
.Reset
DoEvents2
.Execute
End With
SendKeys Password & "~~", True
DoEvents2
If vbProj.Protection <> 1 Then
UnprotectVBProject = True
End If
End Function
' Многократное выполнение DoEvents
Private Sub DoEvents2(Optional ByVal n As Long = 10)
Dim i As Long
For i = 1 To n
DoEvents
Next i
End Sub
Обычно используется Call ключевое слово, если вызванное выражение не начинается с идентификатора. Использование Call ключевого слова для других целей не рекомендуется.
БМВ: на вопрос "как обойтись без SENDKEYS?" - ответ "используете SENDKEYS"
он дал ссылку на тему, в которой есть код Владимира - я только об этом писал. Виктор просто удалил его пост, не вникая (понимаю, почему, и уже писал Марату про участь мальчика, который кричал "волки"), хотя ответ в нём БЫЛ
Цитата
БМВ: исправь, наконец, "Win 8.1 Corp" — Enterprice она, а не Corporate. Да и смысла это указывать тут никакого
ну не факт, что не надо - может это на что-то повлияет. Исправил Corp на Корп, т.к. не нашёл нигде упоминания про Enterprice, а она у меня именно так и записана
Цитата
RAN: DoEvents2 - опечатка?…Совсем слепой стал, не увидел
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Посмотрел ссылку из #2. Код имеет более 300 строк, используется тот же подход, что в #3, вместо SendKeys используются соответствующие низкоуровневые API. Думаю, что эффективность кода такая же. Да, и наверное, в свете нескольких дискуссий на форуме о побочных эффектах оператора SendKeys (NumLock и т.п.) стоит использовать одноименный метод SendKeys объекта WScript.Shell, у которого выявленных подобных недостатков нет.
sokol92 написал: Обычно используется Call ключевое слово, если вызванное выражение не начинается с идентификатора.
Что в коде подразумевается под идентификатором? Почему разработчик не рекомендует? Я использую Call всегда при вызове процедуры из другой процедуры. Так явно видно, что это передача управления, а не что-то другое.
vikttur написал: Что в коде подразумевается под идентификатором?
Это я так (неудачно) пошутил (добавив Off). Цитата относится к VB.Net. Конечно, Call можно использовать, это дело вкуса.
В документации по VBA ключевое слово Call описано как необязательное. Разница возникает при указании параметров при вызове макросов - с Call их надо заключать в скобки, без Call не надо. Вероятно, Call унаследован из старых версий.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Владимир, добрый день. Потестил ваш код. В приложенном файле процедура UnlockVB отрабатывает, пароль (1) снимается. Правда, плюшка в виде отключения NumLock, присутствует в полном объеме. Но при попытке снять код из vbs создается дикое количество экземпляров Excel. Первый раз создалось штук 5, а при повторном запуске – штук 50…Замордовался убивать. Не могу понять, чем вызвана проблема. Путь в скрипте "D:\a\Unlock_VBA.xlsm".
PS vbs в чистом виде не цепляет Unlock.vbs Загружаемые файлы не должны быть размером более 100 Кб.
PPS Вопрос к модераторам Может вопросы фломастеров перенести в другую тему?
Здравствуйте, Андрей! Посмотрел примеры из #17. У меня снятие пароля с проекта работает нестабильно. Причина, может быть, в том, что когда мы открываем первую книгу и выполняем макрос, то, как когда-то заметил Владимир (ZVI), мы работаем в неполной модели Excel. Если обязательно нужен вызов из VBS, то можно открывать специально созданную "стартовую" книгу, в этой книге по событию Workbook_open вызывать через Application.Ontime макрос с нужными действиями. Этот макрос после выполнения всей работы может закрыть Excel.
Экземпляры Excel у меня не зависают после XL.Quit.
Владимир, день добрый. В #17 я пытался создать тестовый файл для проверки фрагмента снятия пароля. По факту структура обработки выглядит примерно так
Т.е. создается несколько экземпляров Excel, каждый из которых обрабатывает файлы в своей папке. Время обработки каждого из потоков до 3 часов. Всего запускается 8 потоков. Ошибка может возникнуть в любом из файлов любого потока. Видимо, придется искать другие варианты решения проблемы
Как любил говорить ikki, потамушта.. Калькулятор содержит ~ 10 листов с формулами + надстройка, и построен так, что оторвать одно от другого не возможно. Тот код, который запускается из VBS, только запускает перебор файлов, причем этот перебор, помимо vbs, может быть запущен и с ленты, и из формы Ну, конечно, не совсем "только перебор", но близко к этому.
Цитата
sokol92 написал: На мой взгляд, Excel не очень приспособлен для пакетных вычислений
совершенно согласен. Более того, изначально этот файл не предназначался для подобных действий. Но годы идут, хотелки растут...
серьезно? у меня хотелка выросла годам к 14-15 и больше ни миллиметра, хотя я в интернете часто скачивал софт и песни именно с тех сайтов, которые гарантировали реальное увеличение размеров....
самолет с пропеллером предназначен для полетов, но не предназначен для полетов в космос (сколько не увеличивай размер пропеллера, скорость его вращения - ничего не получится! нужно менять принцип, нужен реактивный двигатель) по мере развития проекта нужно тонко улавливать момент, когда пора уже сменить транспортное средство)
RAN, да в общем-то все понятно... переделывать с нуля работающий проект - то еще удовольствие но подкрашивать, подпирать костылями - то же приятного мало переделать на основании новых требований (текущего понимания проекта) и забыть (на некоторое время, а может навсегда!) - это перспектива, а постоянно строгать костыли и подпирать с тех сторон куда начало заваливаться - это навсегда((( и конечно, раздавать "умные советы" гораздо проще, чем писать код)
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!