Форум программистов, компьютерный форум, киберфорум
Наши страницы
VBA
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.96/25: Рейтинг темы: голосов - 25, средняя оценка - 4.96
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
1

Маленькое продолжение темы "Аналог Excel-метода "OnTime"" или про многопоточность

02.09.2014, 09:48. Просмотров 4732. Ответов 56
Метки нет (Все метки)

Коллеги, хочу добавить несколько слов ... (раз уж речь зашла про 2003 офис)
Комментарий: на счет глючности версий после 2003 ... извините, IMHO - эта версия наиболее нестабильная на фоне всех после нее вышедших ... жаль, что не собирал баги раньше (их стало значительно меньше. очень значительно!).
Комментарий: если хотите использовать виндовый таймер - 100 раз подумайте. Его использование сопряжено с огромным количеством НО ...

Комментарий: когда-то ... (как раз) в бытность 2003 офиса, использовал один из сторонних OCX-таймеров. Так вот, вопреки всему здавому смыслу и опыту эксперементаторов использовать многопоточность в Экселе - могу вас заверить - получалась НОРМАЛЬНОЕ "многопотоковое"(или псевдомногопотоковое) выполнение кода. Одновременно отрабатывало 2, 3 и более экземпляров вызываемой функции если она не успевала закончить свое выполнение раньше, чем вызывалась ее копия ... Пробовал провернуть такой опыт потом на других версиях - не получалось.
Объяснить? Ни коем разом. Не могу. Но это работало и факт.
(когда-то искал, какие-то ссылки и примеры в интернете были ... но все это было не работающее или работающее сильно не стабильно)

Вопрос: кто пробовал и каких добился результатов на запуск нескольких потоков в VBA? Было бы здорово ...
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.09.2014, 09:48
Ответы с готовыми решениями:

Аналог Excel-метода "OnTime"
Здравствуйте. Что можно использовать вместо Excel-метода "OnTime", чтобы запускать нужную...

Отметить полужирным шрифтом в исходном тексте слова имеющие приставки "пре", "при", "на", "не"
Отметить полужирным шрифтом в исходном тексте слова имеющие приставки "пре", "при", "на", "не"....

Excel: простая формула "Сумм": продолжение
Вот пример: _______________кол-во___цена наименование 1___7_______10 наименование...

Как во всей книге Excel из 10-ти листов удалить " " двойные и более пробелы на " "
Очень хочется удалить во всей книге из 25 тысяч строк более одного пробелов одним махом, решится...

В форме создать кнопку, которая будет изменять текст в определенной строке Excel с "неоплачено" на "оплачено"
Добрый вечер, необходимо в форме создать кнопку которая будет изменять текст в ячейке экселя с...

56
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 10:47 2
Цитата Сообщение от StepInLik Посмотреть сообщение
Его использование сопряжено с огромным количеством НО
Поподробней пожалуйста. Метод OnTime использует SetTimer, VB6 таймер использует SetTimer для таймеров.
Про многопоточность. Поток легко можно создать в DLL/OCX и т.п.
Цитата Сообщение от StepInLik Посмотреть сообщение
кто пробовал и каких добился результатов на запуск нескольких потоков в VBA? Было бы здорово ...
Как ты собираешься отлаживать многопоточный код в однопоточном отладчике? Таймеры вообще не имеют отношения к многопоточности.
0
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 11:24  [ТС] 3
Цитата Сообщение от The trick Посмотреть сообщение
Поподробней пожалуйста. Метод OnTime использует SetTimer, VB6 таймер использует SetTimer для таймеров.
Речь не про OnTimer, а про таймер виндовый. С ним есть много исключений и особенностей поведения, которые сложно контролировать и даже объяснить.
OnTime не отрабатывает если приложение находится в режиме редактирования ячейки ... а это БОЛЬШОЙ МИНУС!
Цитата Сообщение от The trick Посмотреть сообщение
Про многопоточность. Поток легко можно создать в DLL/OCX и т.п.
В данном случае, речь тоже про параллельное выполнение (части) VBA кода.
Часто сталкиваюсь с тем (а таких вариантов может быть много), что не всегда коду VBA удается иметь под рукой требуемую DLL/OCX.
Цитата Сообщение от The trick Посмотреть сообщение
Как ты собираешься отлаживать многопоточный код в однопоточном отладчике?
А никак. Это возможно? Проверять код сотни и сотни раз ... ставить флаги, делить ресурсы, думать что где чем может закончиться ... думать головой и стать интерпретатором.
Не знаю, как тому таймеру удавалось это делать ... какая псевдо- или -потоковость это была ... но функции работали параллельно/одновременно ... каждая из которых пользовались одними внешними переменными и работали из одного модуля ...

Возможно ли осуществить работу нескольких функций (части кода) VBA параллельно из одного приложения?! может кто-то что-то делал? знаю, как-то сам писал что это невозможно, но ...
0
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 11:34 4
Цитата Сообщение от StepInLik Посмотреть сообщение
С ним есть много исключений и особенностей поведения, которые сложно контролировать и даже объяснить.
Приведи пример. Я тебе написал что все эти таймеры так или иначе используют API функцию SetTimer, так что разницы нет.
Цитата Сообщение от StepInLik Посмотреть сообщение
В данном случае, речь тоже про параллельное выполнение (части) VBA кода.
Часто сталкиваюсь с тем (а таких вариантов может быть много), что не всегда коду VBA удается иметь под рукой требуемую DLL/OCX.
Так скорее всего не получится (сделать то можно по-любому), но можно использовать фиберы для эмуляции многопоточности.
Цитата Сообщение от StepInLik Посмотреть сообщение
Не знаю, как тому таймеру удавалось это делать ... какая псевдо- или -потоковость это была ... но функции работали параллельно/одновременно ... каждая из которых пользовались одними внешними переменными и работали из одного модуля ...
А если поставить 2-брейкпоинта, как себя должна вести среда?
Цитата Сообщение от StepInLik Посмотреть сообщение
Возможно ли осуществить работу нескольких функций (части кода) VBA параллельно из одного приложения?! может кто-то что-то делал? знаю, как-то сам писал что это невозможно, но ...
На VB6 возможно, на VBA скорее всего тоже можно, точнее я бы сказал ничто не мешает сделать рабочую многопоточность VBA, если есть знания внутренней работы VBA. А так попробуй фиберы.
0
02.09.2014, 11:34
Антихакер32
Заблокирован
02.09.2014, 11:48 5
Цитата Сообщение от StepInLik Посмотреть сообщение
Комментарий: на счет глючности версий после 2003 ... извините, IMHO - эта версия наиболее нестабильная на фоне всех после нее вышедших ... жаль, что не собирал баги раньше (их стало значительно меньше. очень значительно!).
Скорее всего новые версии больше заточенны на новые системы..
незнаю что там еще микрософт мутит, но мне кажется, своими обновлениями
они вынуждают потребителей раскошеливаться на новое ПО и оборудование

у меня абсолютная идилия с 2003-м офисом, Windows-xp, архитектурой, и средой VB6
тоесть и по скорости, и по настройкам, и по взаимному использованию

Добавлено через 6 минут
Так-же, сомневаюсь, что и на производствах, с большой радостью осваивают неожиданные новшества от майкрософта
0
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 11:58  [ТС] 6
Цитата Сообщение от The trick Посмотреть сообщение
Приведи пример. Я тебе написал что все эти таймеры так или иначе используют API функцию SetTimer, так что разницы нет.
В момент отработки виндового таймера
Было что-то еще ... если интересно - постараюсь вспомнить.
Цитата Сообщение от The trick Посмотреть сообщение
можно использовать фиберы для эмуляции многопоточности
Спасибо. С эмуляцией проблем нет. Речь про реализацию параллельного исполнения без эмуляций.
Цитата Сообщение от The trick Посмотреть сообщение
А если поставить 2-брейкпоинта, как себя должна вести среда?
Помню, тогда не удавалось ставить и одного ...
Весь трейсинг стводился к протоколированию работы каждой строчки каждого вызова функции в свой личный файл, бесчисленные перезапуски и огромная работы по анализу происходящего.
Цитата Сообщение от The trick Посмотреть сообщение
на VBA скорее всего тоже можно, точнее я бы сказал ничто не мешает сделать рабочую многопоточность VBA, если есть знания внутренней работы VBA.
А вот с этим и проблемы.

Добавлено через 5 минут
Цитата Сообщение от Антихакер32 Посмотреть сообщение
Так-же, сомневаюсь, что и на производствах, с большой радостью осваивают неожиданные новшества от майкрософта
Могу заверить вас, что вы сильно ошибаетесь. Коммерческие компании сейчас работают на подписке и поддержке своего софта. Им выгоднее заплатить за новые версии и возможности, чем недополучить прибыль по непонятно каким причинам и ошибкам ... . Нормальные законы рынка.
Поверьте, это практика, с которой сталкивался, сталкиваюсь и буду сталкиваться работая с можеством компаний.
0
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 12:01 7
Цитата Сообщение от StepInLik Посмотреть сообщение
В момент отработки виндового таймера
1 - это ошибка проектирования. Если текст не должен обновляться когда пользователь вводит что-то, значит нужно отключать таймер. К "глючности" системных таймеров это никак не относится.
2 - это я не могу сказать пока не будет примера. Возможно происходит ошибка, а т.к. TimerProc функция обратного вызова происходит вылет, значит нужно устранить ошибку, а потом говорить за таймеры.
Цитата Сообщение от StepInLik Посмотреть сообщение
Весь трейсинг стводился к протоколированию работы каждой строчки каждого вызова функции в свой личный файл, бесчисленные перезапуски и огромная работы по анализу происходящего.
Нда...
Цитата Сообщение от StepInLik Посмотреть сообщение
А вот с этим и проблемы.
В "лоб" пробовал решать? (через CreateThread, CoInitialize) Скорее всего без инициализации контекста это не прокатит или будет работать нестабильно.
0
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 12:12  [ТС] 8
Цитата Сообщение от The trick Посмотреть сообщение
это ошибка проектирования. Если текст не должен обновляться когда пользователь вводит что-то, значит нужно отключать таймер
Как отключать таймер, если события на начало редактирования нет? Приложение не знает когда пользователь начнет или уже начал работать с ячейкой. Таймер как работал, так и работает ... и только при очередном вызове вдруг выясняется, что режим-то редактирования! если продолжать тему, то во-первых эта фича встречается всего на 2 компах(как всегда на самых рабочих и нужных) из сотен в компании, а во-вторых не смотря на то, что таймер тут же отключается - частота вылетов хотя и снизилась во много раз (и система можно сказать стала вести себя стабильно), но все еще продолжает вылетать (видимо во временной период между началом вызова функции отработки таймера, его отключением и окончанием работы функции - что-то иногда успевает отрабатывать, в результате чего эксель и слетает)
И речь не про глючность таймера, а про дополнительные возможные ограничения при его работе. (в частности, в режиме работы таймера нельзя трейсить код ... - это тоже существенное ограничение)
Цитата Сообщение от The trick Посмотреть сообщение
В "лоб" пробовал решать? (через CreateThread, CoInitialize) Скорее всего без инициализации контекста это не прокатит или будет работать нестабильно.
Пробовал (тогда, когда еще было мало опыта). Ничего не получалось. Сейчас не пробовал. Потому и создал тему - есть ли у кого наработки. Если что-то и работает - наверняка там масса ограничений и особенностей работы.
0
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 12:26 9
Цитата Сообщение от StepInLik Посмотреть сообщение
Как отключать таймер, если события на начало редактирования нет? Приложение не знает когда пользователь начнет или уже начал работать с ячейкой. Таймер как работал, так и работает ... и только при очередном вызове вдруг выясняется, что режим-то редактирования!
Это не касается таймеров ни коим образом. Установи ты OCX таймер, сделай ActiveX DLL и там запускай таймер - все будет также работать.
Цитата Сообщение от StepInLik Посмотреть сообщение
в частности, в режиме работы таймера нельзя трейсить код ... - это тоже существенное ограничение)
Можно.
Цитата Сообщение от StepInLik Посмотреть сообщение
Пробовал (тогда, когда еще было мало опыта). Ничего не получалось. Сейчас не пробовал. Потому и создал тему - есть ли у кого наработки. Если что-то и работает - наверняка там масса ограничений и особенностей работы.
Сейчас проверю.
0
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 12:57 10
Простой код у меня работает 2007 Excel -
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
 
Private Const WAIT_TIMEOUT As Long = &H102&
 
Sub Calc()
    Dim hThread As Long
    Dim res     As Long
    
    hThread = CreateThread(ByVal 0&, 0, AddressOf Thread, res, 0, 0)
    
    Do While WaitForSingleObject(hThread, 100) = WAIT_TIMEOUT
        DoEvents
        Debug.Print res
    Loop
    
    CloseHandle hThread
    
End Sub
 
Private Sub Thread(Result As Long)
    Dim i As Long
    
    For i = 0 To 1000000000
        Result = Result + 1
    Next
    
End Sub
Кликните здесь для просмотра всего текста
Маленькое продолжение темы "Аналог Excel-метода "OnTime"" или про многопоточность
1
Вложения
Тип файла: rar Книга1.rar (13.3 Кб, 20 просмотров)
Антихакер32
Заблокирован
02.09.2014, 13:07 11
Я тоже про это упоминал, и именно так и хотел сделать,
пока вы мне нарушение не влипили из за того что я попросил быть вежлевее
WaitForSingleObject
кстати, гдето на форуме у меня есть похожий код, ..

Добавлено через 1 минуту
Спасибо не буду говорить
0
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 13:10 12
Цитата Сообщение от Антихакер32 Посмотреть сообщение
Я тоже про это упоминал, и именно так и хотел сделать
Ну сделал бы, Гуру многопоточности. Какое там упоминание?
0
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 13:23  [ТС] 13
Цитата Сообщение от The trick Посмотреть сообщение
Это не касается таймеров ни коим образом. Установи ты OCX таймер, сделай ActiveX DLL и там запускай таймер - все будет также работать.
Коллега, речь еще и еще раз про таймер в коде VBA - в нем и только нем. Во-первых OСХ и прочие надстройки не всегда доступны, а во-вторых работающий код - это тот, который отрабатывает в теле книги, имеет доступ к объектой модели экселя и работает с данными книги.
Зачем нужен код в OCX и DLL? Коллега. я прекрасно вас понимаю в части работы с VB. Но мы работаем в других рамках, других ограничениях и окружении. У нас нет DLL, у нас нет стандартных компонентов ... и мы даже не знаем где наш код будет запущен (в т.ч. разрядность ОС). Да, это тоже бейсик и те же ключевые слова, разница не большая, но она есть ... и заключается в том, что VBA-код обрабатывается интерпретатором Экселя.
У нас нет возможности таскать за собой ресурсы(а если это бинарник?).
Цитата Сообщение от The trick Посмотреть сообщение
Можно.
Нельзя ))) в VBA - нельзя! поставьте точку останова в функции, которая отрабатывает таймер.
За пример спасибо. Посмотрю.

Не по теме:

Цитата Сообщение от The trick Посмотреть сообщение
Ну сделал бы, Гуру многопоточности.
Цитата Сообщение от Антихакер32 Посмотреть сообщение
пока вы мне нарушение не влипили из за того что я попросил быть вежлевее
Коллеги, простите, не мне делать вам замечание, но не могли бы перенести выяснение оношений в отдельный форум или тему? Не всем интересно читать ваши пререкания. Давайте уважительно относиться к тому, что кто-то что-то знает больше или меньше. и уж тем более - относиться уважительно к тому, что мы развиваемся и делимся друг с другом знаниями.

0
Антихакер32
Заблокирован
02.09.2014, 13:25 14
Цитата Сообщение от StepInLik Посмотреть сообщение
Нельзя ))) в VBA - нельзя!
ну значит нельзя, всемогучий микрософт не предусмотрел такую возможность
а вообще, ни одна серьёзная программа, не обходится без сторонних библиотек программ
ресурсов и прочего барахла, в зависимости от задач, приходится это таскать
сама среда VBA использует около сотни библиотек (если не больше)
0
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 13:34 15
Цитата Сообщение от StepInLik Посмотреть сообщение
Коллега, речь еще и еще раз про таймер в коде VBA - в нем и только нем. Во-первых OСХ и прочие надстройки не всегда доступны, а во-вторых работающий код - это тот, который отрабатывает в теле книги, имеет доступ к объектой модели экселя и работает с данными книги.
Зачем нужен код в OCX и DLL? Коллега. я прекрасно вас понимаю в части работы с VB. Но мы работаем в других рамках, других ограничениях и окружении. У нас нет DLL, у нас нет стандартных компонентов ... и мы даже не знаем где наш код будет запущен (в т.ч. разрядность ОС). Да, это тоже бейсик и те же ключевые слова, разница не большая, но она есть ... и заключается в том, что VBA-код обрабатывается интерпретатором Экселя.
У нас нет возможности таскать за собой ресурсы(а если это бинарник?).
При чем тут это? Видимо ты меня не понял. Я тебе говорю о том, что практически любой таймер использует WinAPI функцию SetTimer. Будь то OnTime или WM_TIMER или еще что-то. OCX и DLL - пример того, что это будет также работать как и при непосредственным применением SetTimer. Ты говоришь таймеру - "тикай" он и тикает, ему неведомо что ты там делаешь, редактируешь или пьешь кофе. Никаких
Цитата Сообщение от StepInLik Посмотреть сообщение
исключений и особенностей поведения, которые сложно контролировать и даже объяснить.
нет.
Цитата Сообщение от StepInLik Посмотреть сообщение
OnTime не отрабатывает если приложение находится в режиме редактирования ячейки ... а это БОЛЬШОЙ МИНУС!
Это уже дело программиста, и особенности Excel'я, таймер как тикал так и тикает, он выполняет свою задачу на 100%.
Цитата Сообщение от StepInLik Посмотреть сообщение
Нельзя ))) в VBA - нельзя! поставьте точку останова в функции, которая отрабатывает таймер.
Ну я бы не стал такое писать если бы не проверил, как ты думаешь?
Кликните здесь для просмотра всего текста
Маленькое продолжение темы "Аналог Excel-метода "OnTime"" или про многопоточность
0
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 13:46  [ТС] 16
Цитата Сообщение от The trick Посмотреть сообщение
Ну я бы не стал такое писать если бы не проверил, как ты думаешь?
Проверьте сами. Пример во вложении.
0
The trick
Модератор
8087 / 2803 / 776
Регистрация: 22.02.2013
Сообщений: 3,952
Записей в блоге: 77
02.09.2014, 13:57 17
Цитата Сообщение от StepInLik Посмотреть сообщение
Проверьте сами. Пример во вложении.
Проверил, все работает
Кликните здесь для просмотра всего текста
Маленькое продолжение темы "Аналог Excel-метода "OnTime"" или про многопоточность
0
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 14:11  [ТС] 18
1. Вы перешли в код
2. Запустили функцию fЗапускТеста
3. Перешли в функцию fФункцияТаймера
4. Установили брекпоинт на строке "dСчетчик& = dСчетчик& + 1"
5. Выполнение кода у вас упало на эту строку
6. Вы подождали пару секунд ... (быть может еще и) отредактировали строчку добавив что-то еще ...
7. Нажали F5 в этой функции и выполнение продолжилось дальше ...
так? если так - подробное видео в студию.
0
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 14:35  [ТС] 19
Сделал тест работы OnTime и виндового таймера. Офис 2010. Запускаю ... и мягко удивляюсь тому, что и таймер и OnTime работают одинаково. В режиме редактирования ячейки - не отрабатывают. (см. пример во вложении)
Сначала было полное недоумениие ... потому как последние 2 года - были огромной пыткой и борьбой с этим парадоксом.
... но нашел 2003 офис и все сомнения пропали. В 2003 все как и прежде - функция на OnTime не отрабатывает, а на виндовый таймер работает вне зависимости от режима работы с ячейкой. (для проверки закомментривать строку вывода в [A1]). И в StatusBar'е при работе таймера - счетчик и время отражается вне зависимости от режима.
То, что OnTime работает на основных принципах работы ОС - вполне очевидная вещь, о чем вообщем, даже говорить не стоит. Так же понятно, что сам таймер отрабатывает всегда. Но отрабатывает ли на его тик ваша программа - вопрос к корректности работы VBA. В новой версии его работа скорректирована.
0
Вложения
Тип файла: rar 2014.09.02 - пример неработоспособности OnTime.rar (17.7 Кб, 11 просмотров)
StepInLik
1063 / 101 / 4
Регистрация: 19.12.2012
Сообщений: 435
02.09.2014, 15:08  [ТС] 20
Фактически, кроме создания самого потока - ничего не работает.
Пример во вложении. Про вывод на лист, в StatusBar, в дебаг или даже в файл - не стоит. (офис 2010)
0
Вложения
Тип файла: rar 2014.09.02 - Потоки.rar (10.6 Кб, 14 просмотров)
02.09.2014, 15:08
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.09.2014, 15:08

Проверить, содержит ли строка символы отличные от "+", "-", "*" и "/"
"+", "-", "*" и "/" вот начал, дальше не знаю что делать Sub rr() Dim s As String,...

Как использовать переменную в Excel/VBA в "объект".Formula="переменная"
Как использовать переменную в Excel/VBA в строке Dim переменная As int Range('A2').Formula =...

MS Acces VBA. Как вывести поле "фамилия" и "группа" из таблицы "студенты" в Access ?
Использовать Fields? Посмотрите в рисунке задания.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.