I'm using Visual Basic Express 2008 to create an interface with a order database in MS Access 2007 (.accdb file). Everything is fully functional except updating the "Inventory" table is very slow. Updating around 2200 items takes almost 2 minutes and the window will appear as "not responding" for the duration if you click away and come back. Here is the process:
1. Tab-delimited text file is picked by user, which includes all inventory items (not just new ones)
2. Each line from text is parsed and read into variables (tempSKU, tempItemTitle, etc.)
3. Old items are updated and new ones are added. -> This is the bottleneck
I used to have a series of IF statements to check which elements were changed and report them, but that was about 2x as slow. The new code is a little faster but doesn't provide the feedback I liked (update part is commented around):
Private Sub btnImportInv_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportInv.Click
Dim strName As String
Dim dlg As Windows.Forms.OpenFileDialog
Dim newSKUAdded As Integer = 0
dlg = New OpenFileDialog()
dlg.Multiselect = False
dlg.InitialDirectory = My.Settings.INVENTORY_REPORT_PATH
dlg.Filter = "txt files (*.txt)|*.txt|" & "All files (*.*)|*.*"
If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
' Count all the lines of the input text file / set progress bar to length
Dim lines As String() = IO.File.ReadAllLines(dlg.FileName)
ProgressBar1.Maximum = lines.Length - 1
For Each strName In dlg.FileNames
Using MyReader As New TextFieldParser(strName)
MyReader.TextFieldType = FieldType.Delimited
MyReader.Delimiters = New String() {vbTab}
Dim currentRow As String()
Dim countRows As Integer = 0
'Loop through all of the fields in the file.
'If any lines are corrupt, report an error and continue parsing.
currentRow = MyReader.ReadFields() 'skip header line in txt
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
Dim currentField As String
Dim inputCounter As Long = 0
Dim tempSKU = ""
Dim tempItemTitle = ""
Dim tempItemNote = ""
Dim tempPrice As Double = 0
For Each currentField In currentRow
inputCounter += 1
Select Case (inputCounter)
Case 1
tempSKU = currentField
Case 2
tempItemTitle = currentField
Case 3
tempItemNote = currentField
Case 4
tempPrice = currentField
End Select
Next
''''''''''''''''''' UPDATE PART (SLOW) ''''''''''''''''''''''''
Try
Me.InventoryTableAdapter.UpdateBySKU(tempSKU, tempItemTitle, tempItemNote, tempItemPrice)
Catch ex As Exception
Me.InventoryTableAdapter.Insert(tempSKU, tempItemTitle, tempItemNote, tempItemPrice)
newSKUAdded += 1
End Try
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Catch ex As MalformedLineException
MsgBox("Line " & ex.Message & " is invalid. Skipping")
End Try
''''''''' PROGRESS BAR CONTROL ''''''''''''''''''
If ProgressBar1.Value < (lines.Length - 1) Then
ProgressBar1.Value += 1
ElseIf ProgressBar1.Value = (lines.Length - 1) Then
ProgressBar1.Value = 1
End If
'''''''''''''''''''''''''''''''''''''''''''''''''
countRows += 1
End While
lstbxRecords.Items.Add("Added: " & newSKUAdded & " new SKUs, and updated the rest")
lstbxRecords.Items.Add(".....Processed " & countRows & " inventory items.....")
End Using
Next
End If
Me.InventoryTableAdapter.Fill(Me.OrderDBDataSet.inventory)
ProgressBar1.Value = 0
End Sub
The UpdateBySKU query is:
UPDATE inventory
SET [itemTitle] = ?, [itemNote] = ?, [price] = ?
WHERE ([SKU] = ?)
I am considering switching to use a SQL express database, not sure if that would boost performance. Also, not sure if using a dataset or something would speed it up (couldn't figure out how to use them yet).
Any suggestions appreciated. Please let me know if any more information is needed, and what kind of speed I should expect doing an operation like this.
Thanks in advance!