Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.01.2012, 01:02   #1
tae1980
Форумчанин
 
Регистрация: 02.02.2009
Сообщений: 842
По умолчанию Как правильно прервать цикл выполнения

Ситуация: при работе с книгой на экране весит форма вызванная в vbModeless режиме. Одновременно с этим пользователь запускает цикл макросов по формированию документов. Внутри этого цикла есть самостоятельная процедура проверки полноты ввода исходных данных (это может быть 3-6 уровень вложенности). Если они не полны пользователю выводиться сообщение об этом с вопросом о продолжении формирования документа да/нет. Если пользователь отвечает "да", все хорошо, но если пользователь отвечает "нет" происходит выход по команде "End" для того что выйти из цепочки любого уровня вложенности (код привожу). При этом закрывается так же и форма открытая в vbModeless режиме.
Вопрос: как выйти из цепочки вызовов с сохранение рабочей формы в режиме vbModeless?
Код:
            rc = MsgBox(Сис_Ошибка, config, Title)
            If rc = vbNo Then End
С уважением, Алексей.
tae1980 вне форума Ответить с цитированием
Старый 05.01.2012, 02:01   #2
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

Цитата:
Вопрос: как выйти из цепочки вызовов с сохранение рабочей формы в режиме vbModeless?
надо корректно написать код.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 05.01.2012, 02:07   #3
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

End - это команда останова ВСЕХ макросов.
Выход из процедуры - Exit sub или exit function
Надо в коде предусматривать возврат с 6 уровня на первый.
Понимаю, что это много кода, - но так уж устроено структурное программирование.

Как сделал бы я:
1) код вывода msgbox в первом уровне вложенности (ни в коем случае не глубже второго!)
2) если так уж нужен msgbox на глубоких уровнях - то только END, и потом всё заново
3) переделал бы весь код, оставив максимум 3 уровня вложенности
(этого достаточно в абсолютном большинстве случаев)

PS: Ничуть не сомневаюсь, что вы отвергнете все 3 моих совета, и опять скажете, что VBA - плохой язык, ибо в REXX это можно было как-то сделать
EducatedFool вне форума Ответить с цитированием
Старый 05.01.2012, 02:10   #4
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Ещё вариант навскидку:

Код:
...

rc = MsgBox(Сис_Ошибка, config, Title)
If rc = vbNo Then application.ontime now+timeserial(0,0,1),"ЗапускФормы": End

...
Код:
sub ЗапускФормы()
userform1.show
end sub
Не уверен, что получится, - но я бы попробовал.
EducatedFool вне форума Ответить с цитированием
Старый 05.01.2012, 02:53   #5
tae1980
Форумчанин
 
Регистрация: 02.02.2009
Сообщений: 842
По умолчанию

Цитата:
Сообщение от EducatedFool Посмотреть сообщение
End - это команда останова ВСЕХ макросов.
Выход из процедуры - Exit sub или exit function
Надо в коде предусматривать возврат с 6 уровня на первый.
Понимаю, что это много кода, - но так уж устроено структурное программирование.
Вопрос не в количестве кода, а в его усложнении. Но выхода похоже нет.
Для решения проблемы на уровне кода, потребуется ввести единый стандарт по форме вызова, с обязательным контролем возврата через if.
Цитата:
Сообщение от EducatedFool Посмотреть сообщение
Как сделал бы я:
1) код вывода msgbox в первом уровне вложенности (ни в коем случае не глубже второго!)
2) если так уж нужен msgbox на глубоких уровнях - то только END, и потом всё заново
3) переделал бы весь код, оставив максимум 3 уровня вложенности
(этого достаточно в абсолютном большинстве случаев)
Я пошел по пути создания универсальных процедур. Вот свел ВСЕ проверки данных в одну процедуру (что было сделать не сложно). И получил побочный эффект: вызывать её можно откуда угодно, с любого уровня. Что оказалось не всегда хорошо. :)) С другой стороны, возникновение подобной проблемы, можно рассматривать как следствия ошибки проектирования.
Вложенность контролировать очень сложно, так как почти все системные функции в той или иной степени универсальны, а степень структурирования весьма велика. Их может вызвать сам пользователь (получаем 2-3 уровень), а могут вызвать и процедуру в "фоновом" режиме (а здесь возможны весьма забавные цепочки).
Цитата:
Сообщение от EducatedFool Посмотреть сообщение
PS: Ничуть не сомневаюсь, что вы отвергнете все 3 моих совета, и опять скажете, что VBA - плохой язык, ибо в REXX это можно было как-то сделать :)
Я мог сказать такое только в шутки или сгоряча. :) Хорошо понимаю, что нет ничего абсолютно хорошего или абсолютно плохого. Вот Си освоить мне так и не удалось (делал две попытки с разницей в 5 лет). Меня бросает в дрожь только от вида всего этого "кошмара".
У меня иная школа и иной опыт. Не скажу, что это хорошо или плохо. Так есть. Может быть со временем мои взгляды и изменятся или просто стану терпимее (читай старее). :))
С уважением, Алексей.
tae1980 вне форума Ответить с цитированием
Старый 05.01.2012, 02:59   #6
tae1980
Форумчанин
 
Регистрация: 02.02.2009
Сообщений: 842
По умолчанию

Цитата:
Сообщение от EducatedFool Посмотреть сообщение
Ещё вариант навскидку:
Код:
...
rc = MsgBox(Сис_Ошибка, config, Title)
If rc = vbNo Then application.ontime now+timeserial(0,0,1),"ЗапускФормы": End
...
Код:
sub ЗапускФормы()
userform1.show
end sub
Не уверен, что получится, - но я бы попробовал.
Я не сомневаюсь что получиться.
Только использования подобного, мне бы очень хотелось избежать. Это не решение проблемы, а обход её. Если рассматривать проблему как ошибку проектирования, то она все равно встанет боком (ещё большим) в другом месте. Лучше решить её сейчас.
С уважением, Алексей.
tae1980 вне форума Ответить с цитированием
Старый 05.01.2012, 10:37   #7
tae1980
Форумчанин
 
Регистрация: 02.02.2009
Сообщений: 842
По умолчанию

Цитата:
Сообщение от EducatedFool Посмотреть сообщение
End - это команда останова ВСЕХ макросов.
Выход из процедуры - Exit sub или exit function
Надо в коде предусматривать возврат с 6 уровня на первый.
Понимаю, что это много кода, - но так уж устроено структурное программирование.
Такой вопрос: может ли процедура (sub) возвращать значение или иной механизм? Может быть есть какой либо код/индекс/прочее правильного выполнения на которое можно повлиять изнутри процедуры.
Я прикидываю как создать систему возврата ошибки без преобразования процедур в функции.
С уважением, Алексей.
tae1980 вне форума Ответить с цитированием
Старый 05.01.2012, 11:23   #8
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Глобальная/публичная переменная?
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 05.01.2012, 11:25   #9
kuklp
Участник клуба
 
Регистрация: 02.05.2010
Сообщений: 1,390
По умолчанию

Кто мешает присвоить значение ошибки глобальной переменной?
Игорь опередил:-)
mailto: kuklp60@gmail.com, ящики для благодарностей:
WM Z206653985942, R334086032478, U238399322728
kuklp вне форума Ответить с цитированием
Старый 05.01.2012, 11:52   #10
tae1980
Форумчанин
 
Регистрация: 02.02.2009
Сообщений: 842
По умолчанию

Цитата:
Сообщение от kuklp Посмотреть сообщение
Кто мешает присвоить значение ошибки глобальной переменной?
Игорь опередил:-)
Ну что же, на этом варианте и остановимся. :)
С уважением, Алексей.
tae1980 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно задать цикл? BingoBongo Общие вопросы Delphi 12 07.05.2011 09:09
Как прервать цикл, когда нажата кнопка какая-нибудь? Karyuudo Общие вопросы Delphi 1 12.04.2010 18:52
не могу разобраться как правильно оформить цикл NICmito Общие вопросы C/C++ 6 17.12.2009 18:01
Как прервать внешний цикл? AndreyF Общие вопросы Delphi 15 15.06.2009 17:46
Как правильно построить цикл для выборки? Tanuska___:) БД в Delphi 1 12.01.2009 14:50