Запуск VBA из программы VB

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Vitaly1
Брехман
Брехман
 
Сообщения: 1578
Зарегистрирован: 30.12.2002 (Пн) 16:35
Откуда: Russia, Mosсow

Запуск VBA из программы VB

Сообщение Vitaly1 » 11.02.2004 (Ср) 12:19

Запускаю через указатель из VB Excel файл. Затем в этом файле может быть запущенна программа VBA через меню Excel. На форме программы VB имеется кнопка, которая закрывает через указатель Excel. Но если программа VBA запущенна, то после клика по указанной кнопке появляется окно собщения, вероятно системное, на наглийском с английскими кнопками что то вроде продолжить и отменить. Можно ли как нибудь сделать, что бы это окно не появлялось, а появлялось окно, с одной кнопкой ОК, и в нем был русский текст - "Пока закрыть файл невозможно, выполняется программа VBA". :?:

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 11.02.2004 (Ср) 14:20

Вряд ли. Это системное окно, выдается в случае если СОМ сервер занят выполнением непрерываемой операции. В данном слчуае в роли СОМ сервера выступает Excel.

SergeySV
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 124
Зарегистрирован: 17.04.2003 (Чт) 14:39
Откуда: Россия, Москва

Сообщение SergeySV » 11.02.2004 (Ср) 14:25

Можно извращаться следующим образом:
через API каждые полсекунды проверяем не появилось ли это окно с ошибкой и тут же его гасим.
Главное двигаться не быстрее, чем думает твоя голова.

Vitaly1
Брехман
Брехман
 
Сообщения: 1578
Зарегистрирован: 30.12.2002 (Пн) 16:35
Откуда: Russia, Mosсow

Сообщение Vitaly1 » 11.02.2004 (Ср) 14:31

А можно код, как это сделать?


Еще вопрос, не будет ли программа VBA Excel, сдерживать "отлов" указанного окна из программы VB?..

SergeySV
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 124
Зарегистрирован: 17.04.2003 (Чт) 14:39
Откуда: Россия, Москва

Сообщение SergeySV » 11.02.2004 (Ср) 14:51

Vitaly1 писал(а):А можно код, как это сделать?


Еще вопрос, не будет ли программа VBA Excel, сдерживать "отлов" указанного окна из программы VB?..


Ууу, тут тебе придется попотеть:
Сначала через программу Spy++ надо глянуть на окно с ошибкой и посмотреть заголовок и класс окна.
Потом поставить таймер и в него включить код:
1. поиск окна по классу
hWnd = FindWindow("NameClass", "WindowCaption")
зная hWnd нашего окна можно его закрыть. Вариантов закрытия окна масса, есть там определенные нюансы, тут тебе подскажут или сам по форуму поищи, если возникнут проблемы с этим. Для начала можно написать просто:
2. If hWnd>0 Then _
DestroyWindow hWnd

Таймер тоже можно сделать через API:
' через 500млсек
SetTimer(hWndMainWindow, 0, 500, AddressOf ProgressTimer)
KillTimer hwnd, 0
ProgressTimer() - это уже твоя (а не API) процедура в которая вызовется при наступлении события OnTimer
Главное двигаться не быстрее, чем думает твоя голова.

corgi
ToyMan
ToyMan
 
Сообщения: 1367
Зарегистрирован: 01.10.2002 (Вт) 9:59
Откуда: Россия, Москва

Сообщение corgi » 11.02.2004 (Ср) 15:35

а нельзя ли как нибудь обойтись без макроса (выполнять этот макрос из vb) и проблем нет :!:
Ничто так не ограничивает полёт мысли программиста, как компилятор

SergeySV
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 124
Зарегистрирован: 17.04.2003 (Чт) 14:39
Откуда: Россия, Москва

Сообщение SergeySV » 11.02.2004 (Ср) 16:36

corgi писал(а):а нельзя ли как нибудь обойтись без макроса (выполнять этот макрос из vb) и проблем нет :!:


Да, это тоже решение. Весь код макроса можно написать и в VB по технологии COM, никто не мешает так сделать. Единственный недостаток - более низкая скорость выполнения. Например: перебрать ячейки в самом Excel быстрее, чем также перебирать их через COM. Тут надо опытно смотреть на сколько будет разница и решать.

>>Еще вопрос, не будет ли программа VBA Excel, сдерживать "отлов" указанного окна из программы VB?..

Небольше чем все остальные запущенные на компьютере программы.
Главное двигаться не быстрее, чем думает твоя голова.

corgi
ToyMan
ToyMan
 
Сообщения: 1367
Зарегистрирован: 01.10.2002 (Вт) 9:59
Откуда: Россия, Москва

Сообщение corgi » 11.02.2004 (Ср) 16:49

другой вариант еще:
1. можно закрытие excel'я отдать юзеру и пускай мучается :D
2. перед закрытием пытаться выполнить маааленькую функцию в VBA и наверно прежде чем выполнится предыдущий макрос она не запустится
Ничто так не ограничивает полёт мысли программиста, как компилятор

SergeySV
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 124
Зарегистрирован: 17.04.2003 (Чт) 14:39
Откуда: Россия, Москва

Сообщение SergeySV » 11.02.2004 (Ср) 17:24

corgi писал(а):другой вариант еще:
1. можно закрытие excel'я отдать юзеру и пускай мучается :D
2. перед закрытием пытаться выполнить маааленькую функцию в VBA и наверно прежде чем выполнится предыдущий макрос она не запустится


Насчет 2 пункта: если ты запустишь в коде VB макрос находящийся в Excel'е, то VB код пойдет дальше, несмотря как выполняется макрос в Excel'e.

Тут можно завести себе глобальную переменную - Dim bolBuzyNow as Boolean, в макросах Excel прописать чтобы в начале они ее устанавливали в True, а в конце выполнения в False. Ну а в самом VB коде после запуска таких макросов запускать функцию WaitExcel.

Declare Function GetInputState Lib "user32" () As Long

Sub WaitExcel()
Do While appExcel...(путь к переменной)......bolBuzyNow
Call loops
If GetInputState() <> 0 Then
DoEvents
End If
Loop
End Sub

Private Function loops()
' пустая функция
End Function

GetInputState - используется только для того, что бы лишний раз не вызывать DoEvents, который пока функция крутит цикл, заставляет программу приостановится, а окну принудительно обработать пришедшие сообщения, ну там пользователь мышкой пошевел или еще что, вот тогда и надо приостановится и обработать пришедшие сообщения.
Главное двигаться не быстрее, чем думает твоя голова.

Vitaly1
Брехман
Брехман
 
Сообщения: 1578
Зарегистрирован: 30.12.2002 (Пн) 16:35
Откуда: Russia, Mosсow

Сообщение Vitaly1 » 11.02.2004 (Ср) 18:55

Послушайте, может скрывать окно формы VB, пока работает макрос, и вновь его показывать, когда макрос выполнился, только как это сделать из VBA, как закрыть окно другого приложения уже расказали, а как его скрыть и показать?

Corgi писал(а):другой вариант еще:
1. можно закрытие excel'я отдать юзеру и пускай мучается

идея очень, и очень не плохая. Правдо, пользователь, пользователю рознь, но наверно, можно научить щелкать на верхний правый крестик, только как указатель на Excel снимать после этого в VB?
Хотя, его можно снимать, перед запуском новой программы, наверное это не вредно?
Нет не выйдет, если окно программы будет видно, то возникнет таже ситуация, при клике по форме, о которой я написал в первом посте!

corgi
ToyMan
ToyMan
 
Сообщения: 1367
Зарегистрирован: 01.10.2002 (Вт) 9:59
Откуда: Россия, Москва

Сообщение corgi » 11.02.2004 (Ср) 20:11

Насчет 2 пункта: если ты запустишь в коде VB макрос находящийся в Excel'е, то VB код пойдет дальше, несмотря как выполняется макрос в Excel'e.

ну ведь макрос может и поменять что-нидь на листе(незаметно для пользователя) а мы это дело обязательно проверим :!:
Правдо, пользователь, пользователю рознь, но наверно, можно научить щелкать на верхний правый крестик, только как указатель на Excel снимать после этого в VB?
Хотя, его можно снимать, перед запуском новой программы, наверное это не вредно?

а ты после запуска экселя отлавливай его hwnd и не соглашайся ничего делать пока этот процесс не завершится :!: :idea:
Ничто так не ограничивает полёт мысли программиста, как компилятор

SergeySV
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 124
Зарегистрирован: 17.04.2003 (Чт) 14:39
Откуда: Россия, Москва

Сообщение SergeySV » 12.02.2004 (Чт) 10:28

corgi писал(а):
Насчет 2 пункта: если ты запустишь в коде VB макрос находящийся в Excel'е, то VB код пойдет дальше, несмотря как выполняется макрос в Excel'e.

ну ведь макрос может и поменять что-нидь на листе(незаметно для пользователя) а мы это дело обязательно проверим :!:


Ну так я про тоже самое и говорил. Мы можем после запуска макроса приостановить выполнение VB кода и подождать выполнение макроса в Excel.
Пример функции ожидания я привел. На что она будет реагировать- выбор большой: можно переменную завести, можно в скрытую ячейку писать можно..... да можно еще целую кучу разных флажков придумать, смысл один, что при обращении к Excel мы могли знать занят он нашим макросом или нет, ну а мы уж в коде VB подождем его.


Вообщем при таком подходе я не очень понимаю, что еще может мешать. Будет форма VB программы висеть, передвигаться и даже перерисовывать. В Excel'e можно даже часики показать на время работы макроса. Тыкнет в Excel мышкой пользователь, а там часики - подожди мол браток пока.
Главное двигаться не быстрее, чем думает твоя голова.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 12.02.2004 (Чт) 11:33

Господа :)
Для синхронизации двух относительно несвязанных процессов в винде всё давно предусмотрено :)
Пусть каждый макрос VBA при своём запуске создаёт mutex с уникальным именем, а при завершении уничтожает. А прога на VB при клике на кнопку пусть проверяет, существует ли mutex с таким именем, и если да, то посылает :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Vitaly1
Брехман
Брехман
 
Сообщения: 1578
Зарегистрирован: 30.12.2002 (Пн) 16:35
Откуда: Russia, Mosсow

Сообщение Vitaly1 » 13.02.2004 (Пт) 10:22

Господа, всем спасибо, ларчик открывался очень просто, я скрываю форму перед закрытием Excel через указатель, и это мешает пользователю кликнуть по кнопке второй раз, и еще сделал переход по ощибке (без этих двух вещей не работало)

Код: Выделить всё
Private Sub Command3_Click()
Form1.Visible = false
On Error Resume Next
Application.Quit
'снять указатель
Set Application = Nothing
Form1.Visible = True
Command3.Visible = false
End Sub


После нажатия на эту кнопку, если VBA работает, форма не появляется, пока не отработает VBA код, а когда отработает, Excel закрывается, и форма появляется.

А если VBA не работает, Excel закрывается сразу, и форма появится сразу.

П.С. Окошко с сообщением вывести при этом нельзя.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 2

    TopList  
cron