Мяв! Началось все с Application.OnTime, но выяснилось, что и Application.Run ведет себя так-же, с той небольшой разницей, что OnTime молчит, а Run ругается на отсутствие макроса. Судя по тому, что код не работает только в модуле формы (в книге и на листе все в порядке), проблема в определении места расположения макроса. В чем причина, и можно-ли как-то прописать запуск? Через доп. код в стандартном модуле работает, вариант не интересен [vba]
Код
Const TimePause = 20 * (1 / 86400 / 10) Private Sub qq() MsgBox "QQ" End Sub Private Sub TextBox1_Change() Application.Run "UserForm1.qq" ' Application.OnTime Now + TimePause, "UserForm1.qq" End Sub
Мяв! Началось все с Application.OnTime, но выяснилось, что и Application.Run ведет себя так-же, с той небольшой разницей, что OnTime молчит, а Run ругается на отсутствие макроса. Судя по тому, что код не работает только в модуле формы (в книге и на листе все в порядке), проблема в определении места расположения макроса. В чем причина, и можно-ли как-то прописать запуск? Через доп. код в стандартном модуле работает, вариант не интересен [vba]
Код
Const TimePause = 20 * (1 / 86400 / 10) Private Sub qq() MsgBox "QQ" End Sub Private Sub TextBox1_Change() Application.Run "UserForm1.qq" ' Application.OnTime Now + TimePause, "UserForm1.qq" End Sub
Через доп. код в стандартном модуле работает, вариант не интересен
Не интересен, потому что хочется ограничиться рамками формы как контейнера кода? Если да, то можно вот так попробовать "почесать ухо другой рукой": [vba]
Через доп. код в стандартном модуле работает, вариант не интересен
Не интересен, потому что хочется ограничиться рамками формы как контейнера кода? Если да, то можно вот так попробовать "почесать ухо другой рукой": [vba]
"-Приезжайте к нам на Колыму. -Нет уж, лучше вы к нам." (С)
Вариант [vba]
Код
'форма Const TimePause = 20 * (1 / 86400 / 10) Sub qq() MsgBox "QQ" End Sub Private Sub TextBox1_Change() ' Application.Run "ww" Application.OnTime Now + TimePause, "ww" End Sub 'стандартный модуль Sub ww() UserForm1.qq End Sub
[/vba] вполне рабочий равно как и [vba]
Код
Const TimePause1 = 20 * (1 / 86400 / 10) Private Sub qqq() MsgBox "QQ" End Sub Private Sub TextBo() Application.Run "ThisWorkbook.qqq" ' Application.OnTime Now + TimePause1, "ThisWorkbook.qqq" End Sub
"-Приезжайте к нам на Колыму. -Нет уж, лучше вы к нам." (С)
Вариант [vba]
Код
'форма Const TimePause = 20 * (1 / 86400 / 10) Sub qq() MsgBox "QQ" End Sub Private Sub TextBox1_Change() ' Application.Run "ww" Application.OnTime Now + TimePause, "ww" End Sub 'стандартный модуль Sub ww() UserForm1.qq End Sub
[/vba] вполне рабочий равно как и [vba]
Код
Const TimePause1 = 20 * (1 / 86400 / 10) Private Sub qqq() MsgBox "QQ" End Sub Private Sub TextBo() Application.Run "ThisWorkbook.qqq" ' Application.OnTime Now + TimePause1, "ThisWorkbook.qqq" End Sub
И? В моем варианте код, вроде как, содержится ТОЛЬКО в форме. Да, незаметно создается временный стандартный модуль, да, незаметно удаляется при закрытии формы, никому не мешает... Тож не годится?
P.S. Добавил булевские переменные bSaved, чтобы манипуляции с временным модулем не заставляли только из-за них сохранять книгу. Также добавил генерацию нового имени временной процедуры subName при каждом новом запуске формы - на случай, если выполнение кода формы вдруг аварийно прервется при предыдущем запуске.
И? В моем варианте код, вроде как, содержится ТОЛЬКО в форме. Да, незаметно создается временный стандартный модуль, да, незаметно удаляется при закрытии формы, никому не мешает... Тож не годится?
P.S. Добавил булевские переменные bSaved, чтобы манипуляции с временным модулем не заставляли только из-за них сохранять книгу. Также добавил генерацию нового имени временной процедуры subName при каждом новом запуске формы - на случай, если выполнение кода формы вдруг аварийно прервется при предыдущем запуске.Gustav
Костя, все хорошо, один минус, но очень БОЛЬШОЙ [vba]
Код
'ВАЖНО: для успешности всего процесса следует включить "галочку" в меню Excel: 'Разработчик / Безопасность макросов/ Параметры макросов / опция "Доверять доступ к объкетной модели VBA" - устанавливаем!
[/vba] И на фоне этого минуса дополнительный код в стандарном модуле вообще сладкая печенька.
Костя, все хорошо, один минус, но очень БОЛЬШОЙ [vba]
Код
'ВАЖНО: для успешности всего процесса следует включить "галочку" в меню Excel: 'Разработчик / Безопасность макросов/ Параметры макросов / опция "Доверять доступ к объкетной модели VBA" - устанавливаем!
[/vba] И на фоне этого минуса дополнительный код в стандарном модуле вообще сладкая печенька.RAN
Быть или не быть, вот в чем загвоздка!
Сообщение отредактировал RAN - Суббота, 15.04.2017, 19:46
по теме: думаю, так (как в 1-м сообщении) сделать невозможно: код относится к классу формы и вызван может быть как метод конкретной реализации "класс -> объект" а объекта пока нет.
ну так это не проблема
по теме: думаю, так (как в 1-м сообщении) сделать невозможно: код относится к классу формы и вызван может быть как метод конкретной реализации "класс -> объект" а объекта пока нет. Саня
все хорошо, один минус, но очень БОЛЬШОЙ 'ВАЖНО: для успешности всего процесса следует включить "галочку" в меню Excel: 'Разработчик / Безопасность макросов/ Параметры макросов / опция "Доверять доступ к объкетной модели VBA"
Уже больше из принципа и нездорового задора, нежели из здравого смысла и практической необходимости, запилил еще вариант - с автоматическим включением (если она перманентно выключена) галки "Доверять доступ" на время работы формы. Вчера и сегодня перекопал довольно много ссылок, в итоге пазл сложился из достаточно разнородных элементов - ну уж сложился как сложился: [vba]
Dim vbmdl As Object 'VBComponent Dim subName As String Dim regKey As String Dim regVal As Integer
Private Sub TextBox1_Change() Application.OnTime Now + TimePause, subName End Sub
Public Sub qq() MsgBox "QQ" End Sub
Private Sub UserForm_Initialize() Dim bSaved As Boolean bSaved = ThisWorkbook.Saved
'проверяем чекбокс "Доверять доступ к объкетной модели VBA" On Error Resume Next regVal = ThisWorkbook.VBProject.VBComponents.Count If Err Then Err.Clear regVal = 0 'чекбокс изначально сброшен Else regVal = 1 'чекбокс изначально установлен End If On Error GoTo 0
'если чекбокс "Доверять" при открытии формы изначально сброшен, 'то устанавливаем его If regVal = 0 Then CreateObject("WScript.Shell").RegWrite regKey, 1, "REG_DWORD" 'т.е. изменяем значение в Реестре, 'но это изменение Excel почему-то немедленно не видит, 'как бы нуждаясь в рефреше, поэтому - 'принудительно жмем кнопку ОК в "Центре управления безопасности", 'причем галка там уже стоит (за счёт операции с Реестром), 'но как бы еще не имеет эффекта - поможем ей! Энтером по кнопке OK SendKeys "{ENTER}" 'посылая упреждающий Энтер в открывающееся следом окно Application.CommandBars.ExecuteMso "MacroSecurity" End If
subName = "temp_" & Format(Now, "YYMMDD_hhmmss") Set vbmdl = ThisWorkbook.VBProject.VBComponents.Add(1)
Private Sub UserForm_Terminate() Dim bSaved As Boolean bSaved = ThisWorkbook.Saved
vbmdl.Collection.Remove vbmdl
'снимаем галку "Доверять", если она была снята в начале 'т.е. подчищаем за собой, восстанавливая начальное состояние If regVal = 0 Then CreateObject("WScript.Shell").RegWrite regKey, 0, "REG_DWORD" SendKeys "{ENTER}" Application.CommandBars.ExecuteMso "MacroSecurity" End If
ThisWorkbook.Saved = bSaved End Sub
[/vba] Самое узкое место - оператор SendKeys "{ENTER}" и следующий за ним оператор открытия диалога "Безопасность макросов", но 99% успешного срабатывания этой парочки, наверное, дам: [vba]
Код
If regVal = 0 Then CreateObject("WScript.Shell").RegWrite regKey, 0, "REG_DWORD" SendKeys "{ENTER}" Application.CommandBars.ExecuteMso "MacroSecurity" End If
[/vba]Впрочем, можно увеличить успех до 100%, если закомментировать SendKeys "{ENTER}", делегировав пользователю почетную обязанность самому явно кликнуть на OK при загрузке и при выгрузке формы.
все хорошо, один минус, но очень БОЛЬШОЙ 'ВАЖНО: для успешности всего процесса следует включить "галочку" в меню Excel: 'Разработчик / Безопасность макросов/ Параметры макросов / опция "Доверять доступ к объкетной модели VBA"
Уже больше из принципа и нездорового задора, нежели из здравого смысла и практической необходимости, запилил еще вариант - с автоматическим включением (если она перманентно выключена) галки "Доверять доступ" на время работы формы. Вчера и сегодня перекопал довольно много ссылок, в итоге пазл сложился из достаточно разнородных элементов - ну уж сложился как сложился: [vba]
Dim vbmdl As Object 'VBComponent Dim subName As String Dim regKey As String Dim regVal As Integer
Private Sub TextBox1_Change() Application.OnTime Now + TimePause, subName End Sub
Public Sub qq() MsgBox "QQ" End Sub
Private Sub UserForm_Initialize() Dim bSaved As Boolean bSaved = ThisWorkbook.Saved
'проверяем чекбокс "Доверять доступ к объкетной модели VBA" On Error Resume Next regVal = ThisWorkbook.VBProject.VBComponents.Count If Err Then Err.Clear regVal = 0 'чекбокс изначально сброшен Else regVal = 1 'чекбокс изначально установлен End If On Error GoTo 0
'если чекбокс "Доверять" при открытии формы изначально сброшен, 'то устанавливаем его If regVal = 0 Then CreateObject("WScript.Shell").RegWrite regKey, 1, "REG_DWORD" 'т.е. изменяем значение в Реестре, 'но это изменение Excel почему-то немедленно не видит, 'как бы нуждаясь в рефреше, поэтому - 'принудительно жмем кнопку ОК в "Центре управления безопасности", 'причем галка там уже стоит (за счёт операции с Реестром), 'но как бы еще не имеет эффекта - поможем ей! Энтером по кнопке OK SendKeys "{ENTER}" 'посылая упреждающий Энтер в открывающееся следом окно Application.CommandBars.ExecuteMso "MacroSecurity" End If
subName = "temp_" & Format(Now, "YYMMDD_hhmmss") Set vbmdl = ThisWorkbook.VBProject.VBComponents.Add(1)
Private Sub UserForm_Terminate() Dim bSaved As Boolean bSaved = ThisWorkbook.Saved
vbmdl.Collection.Remove vbmdl
'снимаем галку "Доверять", если она была снята в начале 'т.е. подчищаем за собой, восстанавливая начальное состояние If regVal = 0 Then CreateObject("WScript.Shell").RegWrite regKey, 0, "REG_DWORD" SendKeys "{ENTER}" Application.CommandBars.ExecuteMso "MacroSecurity" End If
ThisWorkbook.Saved = bSaved End Sub
[/vba] Самое узкое место - оператор SendKeys "{ENTER}" и следующий за ним оператор открытия диалога "Безопасность макросов", но 99% успешного срабатывания этой парочки, наверное, дам: [vba]
Код
If regVal = 0 Then CreateObject("WScript.Shell").RegWrite regKey, 0, "REG_DWORD" SendKeys "{ENTER}" Application.CommandBars.ExecuteMso "MacroSecurity" End If
[/vba]Впрочем, можно увеличить успех до 100%, если закомментировать SendKeys "{ENTER}", делегировав пользователю почетную обязанность самому явно кликнуть на OK при загрузке и при выгрузке формы.Gustav
больше из принципа и нездорового задора, нежели из здравого смысла и практической необходимости
Не смотря на то, что для моей задачи идеально подошло решение doober, ибо он знал, какую задачу я пытаюсь решить, а не только то, как я ее пытаюсь решить, тема получилась интересной и содержательной. а конкретно это
больше из принципа и нездорового задора, нежели из здравого смысла и практической необходимости
Не смотря на то, что для моей задачи идеально подошло решение doober, ибо он знал, какую задачу я пытаюсь решить, а не только то, как я ее пытаюсь решить, тема получилась интересной и содержательной. а конкретно это
Не смотря на то, что для моей задачи идеально подошло решение doober
Хорошо, что уточнил! А то я, было, хотел пожурить, что хоть у doober кратко и гармонично всё получилось, но RAN-то надо, чтобы QQ после каждого символа через 2 сек появлялось, а не после начала набора текста.
Не смотря на то, что для моей задачи идеально подошло решение doober
Хорошо, что уточнил! А то я, было, хотел пожурить, что хоть у doober кратко и гармонично всё получилось, но RAN-то надо, чтобы QQ после каждого символа через 2 сек появлялось, а не после начала набора текста. Gustav
В процессе поиска решения вопрос как решить конкретную задачу плавно трансформировался в вопрос почему именно в форме не работает абстрактный макрос, и как это победить.
В процессе поиска решения вопрос как решить конкретную задачу плавно трансформировался в вопрос почему именно в форме не работает абстрактный макрос, и как это победить. RAN