Как уже было сказано, VBA не поддерживает многопоточность.
Но вам не нужно использовать C # или vbScript для запуска других рабочих потоков VBA.
Я использую VBA для создания рабочих потоков VBA .
Сначала скопируйте книгу makro для каждого потока, который вы хотите запустить.
Затем вы можете запустить новые экземпляры Excel (запущенные в другомThread) просто путем создания экземпляра Excel.Application (чтобы избежать ошибок, я должен установить новое приложение видимым).
Чтобы фактически запустить какую-либо задачу в другом потоке, я могу затем запустить макрос в другом приложении.с параметрами из главной рабочей книги.
Чтобы вернуться в основной поток рабочей книги без ожидания, я просто использую Application.OnTime в рабочем потоке (где он мне нужен).
В качестве семафора я просто используюколлекция, которая используется всеми потоками.Для обратных вызовов передайте основную рабочую книгу в рабочий поток.Там функция runMakroInOtherInstance может быть повторно использована для запуска обратного вызова.
'Create new thread and return reference to workbook of worker thread
Public Function openNewInstance(ByVal fileName As String, Optional ByVal openVisible As Boolean = True) As Workbook
Dim newApp As New Excel.Application
ThisWorkbook.SaveCopyAs ThisWorkbook.Path & "\" & fileName
If openVisible Then newApp.Visible = True
Set openNewInstance = newApp.Workbooks.Open(ThisWorkbook.Path & "\" & fileName, False, False)
End Function
'Start macro in other instance and wait for return (OnTime used in target macro)
Public Sub runMakroInOtherInstance(ByRef otherWkb As Workbook, ByVal strMakro As String, ParamArray var() As Variant)
Dim makroName As String
makroName = "'" & otherWkb.Name & "'!" & strMakro
Select Case UBound(var)
Case -1:
otherWkb.Application.Run makroName
Case 0:
otherWkb.Application.Run makroName, var(0)
Case 1:
otherWkb.Application.Run makroName, var(0), var(1)
Case 2:
otherWkb.Application.Run makroName, var(0), var(1), var(2)
Case 3:
otherWkb.Application.Run makroName, var(0), var(1), var(2), var(3)
Case 4:
otherWkb.Application.Run makroName, var(0), var(1), var(2), var(3), var(4)
Case 5:
otherWkb.Application.Run makroName, var(0), var(1), var(2), var(3), var(4), var(5)
End Select
End Sub
Public Sub SYNCH_OR_WAIT()
On Error Resume Next
While masterBlocked.Count > 0
DoEvents
Wend
masterBlocked.Add "BLOCKED", ThisWorkbook.FullName
End Sub
Public Sub SYNCH_RELEASE()
On Error Resume Next
masterBlocked.Remove ThisWorkbook.FullName
End Sub
Sub runTaskParallel()
...
Dim controllerWkb As Workbook
Set controllerWkb = openNewInstance("controller.xlsm")
runMakroInOtherInstance controllerWkb, "CONTROLLER_LIST_FILES", ThisWorkbook, rootFold, masterBlocked
...
End Sub