Я создаю приложение в Visual Basic Express 2008, которое будет перебирать строки в таблице данных, генерировать соответствующие документы Word mailmerge, затем копировать выходные данные и вставлять их в конец конечного выходного файла. При тестировании все отлично работает, но из-за слияния и процедур копирования/вставки пользовательский интерфейс зависает во время работы. Это нормально для создания документов только для одного файла, но для одного файла требуется около 10-15 секунд. Мы будем использовать этот инструмент для создания документов для сотен файлов, поэтому это может быть проблематично.
Окончательный выходной файл должен быть последовательным. Например, в случае 1 нам нужно создать документы A, B, затем C. Затем перейти к случаю 2 и создать документы A и C. В случае 3 может потребоваться только документ B. И так далее по строкам таблицы данных.
Мне кажется, мне нужно использовать потоки здесь, хотя я новичок в этой концепции и ужасно понимаю. Я понимаю основы этого, но не знаю, как применить к моей программе.
У меня есть цикл For-Next для перебора данных, и для каждой строки он вызывает соответствующие Sub(s). Проблема в том, что подпрограммы, которые он вызывает, нуждаются в данных из исходного файла. Не уверен, как запустить эту логику в потоке с исходными данными. Буду признателен за любой совет, как настроить это в теме.
Я прочитал всю документацию Microsoft, и это имеет смысл, если все, что вы хотите сделать, это посчитать от 0 до 100 или что-то в этом роде.... Не нашел примеров, где исходные данные требуются для многопоточного процесса.
Вот немного, что я хотел бы обернуть в потоке:
For i = 0 To RowCount - 1 'Iterate over the rows in the datatable
SuitBal = SuitData.Rows(i).Field(Of Decimal)("SuitBal")
'Only set courtstate if moving on to the next case and CourtState is not Nothing
If Not SuitData.Rows(i).Field(Of String)("CourtState") Is Nothing _
And SuitData.Rows(i).Field(Of Integer)("Link") = frmCreateDocsByDef.Link Then
frmCreateDocsByDef.CourtState = SuitData.Rows(i).Field(Of String)("CourtState")
End If
'set next account number
frmCreateDocsByDef.fileNum = SuitData.Rows(i).Field(Of Integer)("File")
'Determine if this is a driver account
frmCreateDocsByDef.IsLegalDriver = SuitData.Rows(i).Field(Of Boolean)("IsLegalDriver")
'Determine clientshort name
ClientShort = SuitData.Rows(i).Field(Of String)("ClientShort")
'Determine documents and call subroutines to create and merge
If frmCreateDocsByDef.rbILcase.Checked = True Then
If frmCreateDocsByDef.cbGenerateAuth.Checked = True Then
Call CreateAuth(MyApp, ASSIGN_AUTH, fileDest, OutputFileName, SavePath, "IL", "Suit", frmCreateDocsByDef.fileNum, "")
End If
If frmCreateDocsByDef.cbGenerateECA.Checked = True Then
If ClientShort = "UPH" Then
'Initiate merge
Call CreateECA(UPH_ECA, fileDest, ECAfileName, SavePath, frmCreateDocsByDef.fileNum, "")
'Call CreateUPHECA(UPH_ECA, fileDest, ECAFileName, SavePath, fileNum, "")
If frmCreateDocsByDef.IsLegalDriver = True Then
'Call CreateUPHFAP(UPH_FAP, fileDest, ECAFileName, SavePath, fileNum, Link, "")
Call CreateFAP(UPH_FAP, fileDest, ECAfileName, SavePath, frmCreateDocsByDef.fileNum, frmCreateDocsByDef.Link, "")
End If
ElseIf ClientShort = "HARRISBURG" Then
'Call CreateHarrisburgECA(HMC_ECA, fileDest, ECAFileName, SavePath, fileNum, "")
Call CreateECA(HMC_ECA, fileDest, ECAfileName, SavePath, frmCreateDocsByDef.fileNum, "")
If frmCreateDocsByDef.IsLegalDriver = True Then
'Call CreateHarrisburgFAP
Call CreateFAP(HMC_FAP, fileDest, ECAfileName, SavePath, frmCreateDocsByDef.fileNum, "")
End If
End If
'Call HMC ECA
End If
ElseIf frmCreateDocsByDef.rbIAcase.Checked = True Then
If frmCreateDocsByDef.rb1Def.Checked = True Then
'generate Verfications for 1 defendant
If frmCreateDocsByDef.cbGenerateVfn.Checked = True And _
(frmCreateDocsByDef.rbAllAcctsInCase.Checked = True And frmCreateDocsByDef.IsLegalDriver = True) Or _
frmCreateDocsByDef.rbSingleAcct.Checked = True Then
Call CreateIowaVerifications(MyApp, IA_VFN_1DEF, fileDest, OutputFileName, SavePath, frmCreateDocsByDef.fileNum, "")
End If
'generate affidavits for 1 defendant
If frmCreateDocsByDef.cbGenerateAffidavit.Checked = True And _
(frmCreateDocsByDef.rbAllAcctsInCase.Checked = True And frmCreateDocsByDef.IsLegalDriver = True) Or _
frmCreateDocsByDef.rbSingleAcct.Checked = True Then
Call CreateIowaAffidavits(MyApp, IA_AFFID_1DEF, fileDest, OutputFileName, SavePath, frmCreateDocsByDef.fileNum, "")
End If
'generate authorizations for 1 defendant
If frmCreateDocsByDef.cbGenerateAuth.Checked = True Then
Call CreateAuth(MyApp, SUIT_AUTH, fileDest, OutputFileName, SavePath, "IA", "Suit", frmCreateDocsByDef.fileNum, "")
End If
ElseIf frmCreateDocsByDef.rb2Defs.Checked = True Then
'generate docs for 2 defendants
End If
ElseIf frmCreateDocsByDef.rbWIcase.Checked = True Then
End If
Next
Я попытался создать новый Sub под названием «MergeDocsByDef()» без параметров и поместил все это туда, а затем попытался запустить поток, но MergeDocsByDef не смог прочитать исходные данные из таблицы данных. Поэтому я добавил параметры в MergeDocsByDef и попробовал еще раз, но тогда это не разрешилось, когда я изменил его на Dim Th = New Thread(AddressOf MergeDocsByDef(param1, param2))
.
Итак... если код, который я хочу использовать в потоке, перебирает данные и/или требует параметров, как мне использовать поток? Или, может быть, «настоящий» вопрос: как мне заставить пользовательский интерфейс не зависать во время слияния почты, сохраняя при этом выходной файл в порядке с таблицей данных?