I am building an application in Visual Basic Express 2008 that will iterate over rows in a datatable, generate the appropriate Word mailmerge document(s), then copy the output and paste at the end of the final output file. Everything works great in testing, but because of the mailmerge and the copy/paste procedures, it hangs the UI while it's running. It's ok for generating docs on just one file, but it takes about 10-15 seconds for one file. We will be using this tool to generate documents for hundreds of files, so it could be problematic.
The final output file must be sequential. For example, on case 1, we need to create Documents A, B, then C. Then move to case 2 and create documents A and C. Case 3 might only require document B. And so on throughout the rows of the datatable.
Seems to me I need to use threading here although I am new to the concept and having a terrible time understanding. I get the basics of it, but unsure how to apply to my program.
I have a For-Next loop to iterate over the datatable and for each row, it calls the appropriate Sub(s). Problem is the subs it calls need data from the source file. Not sure how to run this logic within a thread given the source data. Would appreciate any advice on how to set this up in a thread.
I have read all the Microsoft documentation and it makes sense if all you want to do is count from 0 to 100 or something like that.... Haven't found any examples where source data is required for the threaded process.
Here's the bit I would like to wrap up in a thread:
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
I tried creating a new Sub called "MergeDocsByDef()" with no parameters and put all this in there and then tried starting thread, but MergeDocsByDef couldn't read any of the source data from the datatable. So I added parameters to MergeDocsByDef and tried again, but then it wouldn't allow it when I changed it to Dim Th = New Thread(AddressOf MergeDocsByDef(param1, param2))
.
So... if the code that I want to use in a thread iterates over a datatable and/or requires parameters, how do I use a thread? Or maybe the "real" question: How do I get the UI to not freeze up while the mail merge is taking place, while keeping the output file in order with the datatable?