I am trying to develop a simple bulk copy program that polls a given folder for files at specified intervals.
The code looks perfect. My output gives a great recursive list of files, but when I go to actually move them according to the list, every file I scanned is locked. I have tried garbage collecting, disposing, exiting subs at certain points, debugging at certain points...
Please take a look at my code. When MoveFile is called, everything is locked.
Imports System
Imports System.IO
Public Structure FileStructure
Dim Enumerator As Integer
Dim SPath As String
Dim DPath As String
Dim Name As String
Dim FileSize As Long
Dim IsFile As Short
Dim SourceFullName As String
Dim DestFullName As String
End Structure
Public Class StagingDriveCoordinator
Dim FilesScanned As FileStructure()
Dim ScanCount As Integer = -1
Private Sub ScanAll(ByVal sourcePath As String, ByVal destinationPath As String)
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(sourcePath)
' ---------------------- Create the appropriate directories --------------------------------
' Create source path
If Not System.IO.Directory.Exists(sourcePath) Then
System.IO.Directory.CreateDirectory(sourcePath)
End If
' If the destination folder doesn't exist then create it
If Not System.IO.Directory.Exists(destinationPath) Then
System.IO.Directory.CreateDirectory(destinationPath)
End If
' ------------------------------------------------------------------------------------------
Dim AddSize As Integer = 0
'Figure out how much to resize the array this iteration of ScanAll
If FilesScanned IsNot Nothing Then
AddSize = FilesScanned.Count + sourceDirectoryInfo.GetFileSystemInfos.Length
Else
AddSize = sourceDirectoryInfo.GetFileSystemInfos.Length
End If
'Resize the array
Array.Resize(FilesScanned, AddSize)
For Each FileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
ScanCount += 1
FilesScanned(ScanCount).Enumerator = ScanCount
FilesScanned(ScanCount).SPath = sourcePath.ToString
FilesScanned(ScanCount).DPath = destinationPath.ToString
FilesScanned(ScanCount).Name = FileSystemInfo.Name.ToString
If TypeOf FileSystemInfo Is System.IO.FileInfo Then
FilesScanned(ScanCount).FileSize = DirectCast(FileSystemInfo, FileInfo).Length
FilesScanned(ScanCount).IsFile = 1
Else
FilesScanned(ScanCount).FileSize = 9223372036854775807
FilesScanned(ScanCount).IsFile = 0
End If
FilesScanned(ScanCount).SourceFullName = System.IO.Path.Combine(sourcePath, FileSystemInfo.Name).ToString
FilesScanned(ScanCount).DestFullName = System.IO.Path.Combine(sourcePath, FileSystemInfo.Name).ToString
txtOutput.Text += FilesScanned(ScanCount).Enumerator & vbTab & FilesScanned(ScanCount).SourceFullName & vbNewLine
If FilesScanned(ScanCount).IsFile = 0 Then
'Debug
txtOutput.Text += vbNewLine & "Recursively scanning subfolder " + FilesScanned(ScanCount).Name & "..." + vbNewLine + vbNewLine
'Recursively call the main scanner.
ScanAll(FilesScanned(ScanCount).SourceFullName, FilesScanned(ScanCount).DestFullName)
End If
Next
End Sub
Private Sub MoveFile(ByVal Source, ByVal Destination, ByVal filesize)
Try
File.Copy(Source, Destination, True)
txtOutput.Text += "Moving file... Source: " & Source & ". Filesize: " & filesize.ToString & vbNewLine
txtOutput.Text += "Destination: " & Destination & vbNewLine & vbNewLine
File.Delete(Source)
Catch ex As Exception
txtOutput.Text += "File " & Source & " is locked." & vbNewLine
End Try
End Sub
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Select Case cmbPollingFrequency.SelectedItem
Case "5 Seconds"
Timer1.Interval = 5000
Case "30 Seconds"
Timer1.Interval = 30000
Case "1 Minute"
Timer1.Interval = 60000
Case "5 Minutes"
Timer1.Interval = 300000
Case "15 Minutes"
Timer1.Interval = 900000
Case "30 Minutes"
Timer1.Interval = 1800000
Case "1 Hour"
Timer1.Interval = 3600000
Case Else
MsgBox("You must select an interval.")
End Select
Timer1.Start()
End Sub
Private Sub TimerTick(sender As Object, e As EventArgs) Handles Timer1.Tick
Timer1.Stop()
txtOutput.Text += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") & vbNewLine
txtOutput.Text += "Scanning Filesystem..." + vbNewLine + vbNewLine
'Scan the file system.
ScanAll(cmbStaging.Text, cmbBackup.Text)
txtOutput.Text += vbNewLine
txtOutput.Text += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") & vbNewLine
txtOutput.Text += " ------------- Scan cycle completed. --------------- " & vbNewLine & vbNewLine
txtOutput.Text += "Sorting by filesize..." & vbNewLine & vbNewLine
' Sort the file list by size.
FilesScanned = FilesScanned.OrderBy(Function(x) x.FileSize).ToArray
txtOutput.Text += "Done." & vbNewLine & vbNewLine
txtOutput.Text += "Moving smallest files first..." & vbNewLine & vbNewLine
For Each FileElement In FilesScanned
If FileElement.IsFile > 0 Then
'file.FileSize only needed to pass size to text output
MoveFile(FileElement.SourceFullName, FileElement.DestFullName, FileElement.FileSize)
End If
Next
FilesScanned = Nothing
ScanCount = -1
Timer1.Start()
End Sub
Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
Timer1.Stop()
End Sub
End Class
I found the problem. The IO system was NOT locking the file. I was trying to copy it to the SAME directory...
FilesScanned(ScanCount).SourceFullName =
System.IO.Path.Combine(sourcePath, FileSystemInfo.Name).ToString
FilesScanned(ScanCount).DestFullName =
System.IO.Path.Combine(sourcePath, FileSystemInfo.Name).ToString
This should have been:
FilesScanned(ScanCount).SourceFullName =
System.IO.Path.Combine(sourcePath, FileSystemInfo.Name).ToString
FilesScanned(ScanCount).DestFullName =
System.IO.Path.Combine(destinationPath, FileSystemInfo.Name).ToString
Once I changed it, everything worked perfectly.
Related
I have a VB windows form application that has 02 ComboBox that provide newname input for a renaming file event. The first combobox provide prefix for new name comprise items (aa, bb, cc,... can add more through keydown button click event), the other combobox provide main name comprise items (XX, YY, ZZ,.. can also add more through keydown button click event). When I select "aa" from the first combobox, "XX" from the other then fire the rename event, the new file name should be "aa - XX", if file "aa - XX" has already existed then add "1" to the last as "aa - XX 1" and so on and if no item selected in prefix combobox the newname just be "XX" and increment. I get the old file name through a system openfiledialog. My code for rename as follows:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim var As String, prfix As String
var = ComboBox1.Text
prfix = ComboBox2.Text
If ComboBox2.Text = Nothing Then
If File.Exists(n & "\" & var & extn) = False Then
My.Computer.FileSystem.RenameFile(OpenFD.FileName, var & extn)
Else
Dim i As Integer = 1
Dim newfn As String = var & " " & i & extn
Dim m As String = n & "\" & newfn
While File.Exists(m)
newfn = var & " " & i & extn
m = n & "\" & newfn
i += 1
End While
My.Computer.FileSystem.RenameFile(OpenFD.FileName, newfn)
End If
Else
If File.Exists(n & "\" & prfix & " - " & var & extn) = False Then
My.Computer.FileSystem.RenameFile(OpenFD.FileName, prfix & " - " & var & extn)
Else
Dim j As Integer = 1
Dim newfn1 As String = prfix & " - " & var & " " & j & extn
Dim k As String = n & "\" & newfn1
While File.Exists(k)
newfn1 = var & " " & j & extn
k = n & "\" & newfn1
j += 1
End While
My.Computer.FileSystem.RenameFile(OpenFD.FileName, newfn1)
End If
End If
MessageBox.Show("Select a next file")
End Sub
My code run well 2 times. After I select "aa" and "XX" and leave it to rename, first result is "aa - XX", the second result is "aa - XX 1" but the third result is "XX", the forth is "XX 1" and then incrementing so on while the result should be "aa - XX 2" and next increment. I don't understand why combobox1 still effective but combobox2 as Nothing after no re-selecting the item in both comboboxes (2 times). I'm very new with VB so any advice should be much appreciated. Thanks.
In your lower Else block, you were incorrectly building up the file name.
You build up the first "newfn1" with:
Dim newfn1 As String = prfix & " - " & var & " " & j & extn
But then below, you used:
newfn1 = var & " " & j & extn
Notice the missing prefix and dash parts at the beginning.
Here's the full corrected version:
Dim j As Integer = 1
Dim newfn1 As String = prfix & " - " & var & " " & j & extn
Dim k As String = Path.Combine(n, newfn1)
While File.Exists(k)
j = j + 1
newfn1 = prfix & " - " & var & " " & j & extn
k = Path.Combine(n, newfn1)
End While
My.Computer.FileSystem.RenameFile(OpenFD.FileName, newfn1)
I'm a little confused by your explanation but if I understand correctly this should help,
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
CreateFile()
End Sub
Private BasePath As String = "" 'TODO
Private Ext As String = "txt"
Private Sub CreateFile()
If ComboBox1.SelectedIndex < 0 OrElse
ComboBox2.SelectedIndex < 0 OrElse
ComboBox1.SelectedItem.ToString = "" OrElse
ComboBox2.SelectedItem.ToString = "" Then
'error message
Exit Sub
End If
Dim fileName As String = String.Format("{0}-{1}.{2}",
ComboBox1.SelectedItem.ToString,
ComboBox2.SelectedItem.ToString,
Ext)
fileName = IO.Path.Combine(BasePath, fileName)
Dim ct As Integer = 1
Do While IO.File.Exists(fileName)
fileName = String.Format("{0}-{1}{3}.{2}",
ComboBox1.SelectedItem.ToString,
ComboBox2.SelectedItem.ToString,
Ext,
ct)
fileName = IO.Path.Combine(BasePath, fileName)
ct += 1
Loop
Dim fs As IO.FileStream = IO.File.Create(fileName)
fs.Close()
fs.Dispose()
End Sub
This is my first vb.net program, so please bear with me if my question is very mediocre.
Before mentioning my problem, the mechanism of my accounting program is that if the user would input data into the datagridview and export it, so that when he restarts the program, he can import the exported data.
I have imported this .csv file to my datagridview
The problem is that when I have imported it, only column texts would appear like this.
This is the export code that I have used to create the .csv file.
Private Sub ExportToExcelToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExportToExcelToolStripMenuItem.Click
Dim msg1 = "Export Successful"
Dim title = "Excel Export"
MsgBox(msg1, , title)
Try
Dim iexport1 As String = ""
Dim eexport1 As String = ""
For Each C As DataGridViewColumn In Income.Columns
iexport1 &= """" & C.HeaderText & ""","
Next
iexport1 = iexport1.Substring(0, iexport1.Length - 1)
iexport1 &= Environment.NewLine
For Each R As DataGridViewRow In Income.Rows
For Each C As DataGridViewCell In R.Cells
If Not C.Value Is Nothing Then
iexport1 &= """" & C.Value.ToString & ""","
Else
iexport1 &= """" & "" & ""","
End If
Next
iexport1 = iexport1.Substring(0, iexport1.Length - 1)
iexport1 &= Environment.NewLine
Next
For Each C As DataGridViewColumn In Expense.Columns
eexport1 &= """" & C.HeaderText & ""","
Next
eexport1 = eexport1.Substring(0, eexport1.Length - 1)
eexport1 &= Environment.NewLine
For Each R As DataGridViewRow In Expense.Rows
For Each C As DataGridViewCell In R.Cells
If Not C.Value Is Nothing Then
eexport1 &= """" & C.Value.ToString & ""","
Else
eexport1 &= """" & "" & ""","
End If
Next
eexport1 = eexport1.Substring(0, eexport1.Length - 1)
eexport1 &= Environment.NewLine
Next
Dim tw As IO.TextWriter = New IO.StreamWriter(path:="C:\Users\S2009516\Desktop\JanuaryIncome.CSV")
tw.Write(iexport1)
tw.Close()
Dim tw2 As IO.TextWriter = New IO.StreamWriter(path:="C:\Users\S2009516\Desktop\JanuaryExpense.CSV")
tw2.Write(eexport1)
tw2.Close()
Catch ex As Exception
End Try
End Sub
And this is the one I have used for importing csv file.
Private Sub ImportFromExcelToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ImportFromExcelToolStripMenuItem.Click
Dim expenseload1 As String = "C:\Users\S2009516\Desktop\JanuaryExpense.CSV"
Dim incomeload1 As String = "C:\Users\S2009516\Desktop\JanuaryIncome.CSV"
Try
Dim expensereader1 As New StreamReader(expenseload1, Encoding.Default)
Dim incomereader1 As New StreamReader(incomeload1, Encoding.Default)
Dim eline As String = ""
Dim iline As String = ""
Do
eline = expensereader1.ReadLine
iline = incomereader1.ReadLine
If eline Is Nothing Then Exit Do
If iline Is Nothing Then Exit Do
Dim words() As String = eline.Split(",")
Dim words2() As String = iline.Split(",")
Income.Rows.Add("")
Expense.Rows.Add("")
For ix As Integer = 0 To 3
Me.Income.Rows(Income.Rows.Count - 1).Cells(ix).Value = words2(ix)
Me.Expense.Rows(Income.Rows.Count - 1).Cells(ix).Value = words(ix)
Next
Loop
expensereader1.Close()
incomereader1.Close()
Catch ex As Exception
End Try
End Sub
I have no clue on why this is happening... I have followed all the steps in the tutorial video.. Please save my soul... I have been stuck with this for 2 days already.
I wrote a code to show/hide content of a certain DataTable into a DataGridView.
DataGridView appears and disappears when I click a button.
I don't get errors but nothing is shown.
But if I click another button (who shows another form) and then go back to the main form, the code works. (??!!??)
I wasn't able to understand what (in the 2nd code) makes the first code to work: it seems there aren't connections between two codes.
EDIT
I made some tests and I can add more informations:
I added a button to show (in a msgbox) the DataGridView properties.
The control was correctly added and all properties are correct.
The property "Visible" is set "True" but the DataGridView is still "invisible".
I added a button that sets DGV_Tbl.Visible = False and DGV_Tbl.Visible = True
And when I click it the DataGridView appears.
But if I click Btn_ShowHideTbl again (to remove DGV) and again (to re-add DGV) DataGridView is still "invisible".
This doesn't happens when I click the button to open the second form and then I close it to go back to the first form.
In this case all works correctly.
I could solve adding DGV_Tbl.Visible = False and DGV_Tbl.Visible = True to the first code but I don't think it's a good idea.
I would like to understand the problem and solve it without "strange instructions".
EDIT 2
I noticed that also the code .AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells) doesn't work without opening the 2nd form.
On this istruction DGV_Tbl.Visible = False and DGV_Tbl.Visible = True haven't effect.
EDIT 3
I've done as in the accepted answer, but I posted another question here hoping to understand what's wrong in my code.
This is my code to show/hide DataGridView:
Private Sub Btn_ShowHideTbl_Click(sender As Object, e As EventArgs) Handles Btn_ShowHideTbl.Click
ShowHideTbl()
End Sub
Private Sub ShowHideTbl()
'Look for DGV
Dim DGV_Tbl As DataGridView = Nothing
Try
DGV_Tbl = CType(Me.Controls("DGV_Tbl"), DataGridView)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Try
'If not found I need to show data
If DGV_Tbl Is Nothing Then
If Me.CBox_ProcType.Text = "Select a Procedure" Then
MsgBox("You need To select a Procedure", vbInformation, "Unable to show table")
Exit Sub
End If
DGV_Tbl = New DataGridView
'It needs to copy data to another DataTable to show Double as Currency
Using DTemp As DataTable = New DataTable
Dim TblName As String = Me.CBox_ProcType.Text
For C As Integer = 0 To DS_All.Tables(TblName).Columns.Count - 1
DTemp.Columns.Add(DS_All.Tables(TblName).Columns(C).ColumnName, Type.GetType("System.String"))
Next
Dim Arr(DS_All.Tables(TblName).Columns.Count - 1) As String
For R As Integer = 0 To DS_All.Tables(TblName).Rows.Count - 1
For C As Integer = 0 To DS_All.Tables(TblName).Columns.Count - 1
If C = 0 Then
Arr(C) = DS_All.Tables(TblName).Rows(R)(C).ToString
Else
Arr(C) = FormatCurrency(DS_All.Tables(TblName).Rows(R)(C).ToString, 2)
End If
Next
DTemp.Rows.Add(Arr)
Next
'Working on created DataGridView
With DGV_Tbl
.Name = "DGV_Tbl"
'Add control to the Form
Me.Controls.Add(DGV_Tbl)
.DataSource = DTemp
.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)
.RowHeadersVisible = False
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
End With
'Dispose the copied DataTable
End Using
'Resizing Form to include new DataGridView
Dim DGV_H As Integer = 0
Dim DGV_W As Integer = 0
For Each R As DataGridViewRow In DGV_Tbl.Rows
DGV_H += R.Height
Next
DGV_H += DGV_Tbl.ColumnHeadersHeight
'Add more space to include spaces between cells
DGV_H += CInt(DGV_Tbl.Rows.Count * 0.45)
For Each C As DataGridViewColumn In DGV_Tbl.Columns
DGV_W += C.Width
Next
'Add more space to include spaces between cells
DGV_W += CInt(DGV_Tbl.Columns.Count * 0.45)
DGV_Tbl.Height = DGV_H
DGV_Tbl.Width = DGV_W
'Resize the Form
Me.Height += DGV_H + 30
Me.Controls("DGV_Tbl").Location = New Point(15, Me.Height - DGV_H - 30)
'Align for currency
For x As Integer = 1 To DGV_Tbl.Columns.Count - 1
DGV_Tbl.Columns(x).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
Next
Else
'If DGV exists I need to remove it and resize the form
Dim DGV_H As Integer = DGV_Tbl.Height
DGV_Tbl.Dispose()
Me.Height -= (DGV_H + 30)
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
This is the code in the button who shows another form (and the code to close the form and go back):
Private Sub Btn_ShowSummary_Click(sender As Object, e As EventArgs) Handles Btn_ShowSummary.Click
Try
If Me.CBox_ProcType.Text = "Select a Procedure" OrElse Me.CBox_ProcValue.Text = "Select a Value" Then
MsgBox("It needs to select a Procedure and a Value",
vbInformation, "Unable to show table")
Exit Sub
End If
Summary = "...Here Some text..." & vbCrLf & Split(Me.CBox_ProcType.Text, ".")(1).Trim & vbCrLf & vbCrLf
Summary &= "...Here Some text..." & Me.CBox_ProcValue.Text & vbCrLf & vbCrLf
Dim C1Wdt% = -50
Dim C2Wdt% = TBox_TotAll.Text.Length
For R As Integer = 1 To 4
Dim CBox_Phase As CheckBox = CType(Me.TLP_Phases.Controls("CBox_Phase" & R.ToString), CheckBox)
Dim TBox_ValPh As TextBox = CType(Me.TLP_Phases.Controls("TBox_ValPh" & R.ToString), TextBox)
If CBox_Phase.Checked Then
Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
CBox_Phase.Text, TBox_ValPh.Text) & vbCrLf
Dim TBox_SelVarPh As TextBox = CType(Me.TLP_Phases.Controls("TBox_SelVarPh" & R.ToString), TextBox)
If TBox_SelVarPh.Text = "" OrElse TBox_SelVarPh.Text = "€ 0,00" Then
Summary &= "...Here Some text..." & vbCrLf
Else
Dim SelVarTxt$ = If(Val(TBox_SelVarPh.Text) > 0,
"...Here Some text..." & TBox_SelVarPh.Text,
"...Here Some text..." & TBox_SelVarPh.Text.Substring(1)) & vbCrLf
Summary &= SelVarTxt
End If
End If
Next
Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}", "", New String(CChar("_"), C2Wdt)) & vbCrLf
Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
"...Here Some text...",
Me.TBox_TotPhases.Text) & vbCrLf
If Me.TBox_PrtAdg.Text <> "€ 0,00" Then
Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
"...Here Some text...",
Me.TBox_PrtAdg.Text) & vbCrLf
Summary &= "...Here Some text..." & TBox_PrtRapp.Text & "...Here Some text..." & TBox_CPrt.Text & "...Here Some text..." & vbCrLf
End If
Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
"...Here Some text..." & TBox_ForfPercent.Text,
Me.TBox_ForfImp.Text) & vbCrLf
Summary &= "...Here Some text..." & TBox_TotPhases.Text & ")" & vbCrLf
Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}", "", New String(CChar("_"), C2Wdt)) & vbCrLf
Summary &= String.Format("{0," & C1Wdt.ToString & "} {1," & C2Wdt.ToString & "}",
"...Here Some text...",
Me.TBox_TotAll.Text) & vbCrLf
Me.Hide()
Me.ShowInTaskbar = False
Frm_Summary.Show()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Here the code of the back button:
Private Sub Btn_CloseNBack_Click(sender As Object, e As EventArgs) Handles Btn_CloseNBack.Click
Frm_Base.ShowInTaskbar = True
Frm_Base.Show()
Me.Close()
End Sub
I don't see any connetion between the codes (but it seems I'm wrong) please show me what I'm missing.
May I suggest another approach for your problem ?
If i were you, i would think about using a drawn datagridview, put datatable content into it before hand.
Then in the show/hide button, just switch the visibility of that datagridview along with recalculating the form size.
As for the currency column, instead of making another table, you can just populate the datatable into your datagridview, then set the format of that column into currency:
DGV_Tbl.Columns("CurrencyColumn").DefaultCellStyle.Format = "c"
More information about datagridview column formatting can be found here
Everything I read points me to the need to run my "CollectSample" function in a backgroundworker1 but using all the samples I can't figure it out or compile. Because I am very new to vb, and not a strong programmer, I can't figure out how to invoke, or use background worker in the following code. A quick summary, I am calling realterm as a process and it opens and closes just fine, but locks out win form and because its in a loop of 16, I can't breakout if needed? Any help or guidance would be appreciated.
Private Sub Button35_Click(sender As Object, e As EventArgs) Handles Button35.Click
ProgressBar2.Visible = True
ProgressBar2.Value = 0
For i As Integer = 17 To 32
DirectCast(Me.Controls.Find("Button" & i, True)(0), Button).Visible = False
Next
For Bindex = 17 To 32
Dim Counter As Integer = 0
Dim Tone As Integer = TextBox1.Text
Dim Duration As Integer = TextBox2.Text
Duration = Duration * 2
For Counter = 1 To Duration
Counter = Counter + 1
NtBeep(Tone, 200) 'f,d
Next
CollectSample("SAMPLE" & Bindex - 16 & ".txt") 'subtracting the first 16
ProgressBar2.PerformStep()
CheckSample("SAMPLE" & Bindex - 16 & ".txt")
DirectCast(Me.Controls.Find("Label" & Bindex, True)(0), Label).Visible = True
DirectCast(Me.Controls.Find("Button" & Bindex, True)(0), Button).Visible = True
If SampleFlag = 1 Then 'error readiing from instument
DirectCast(Me.Controls.Find("Label" & Bindex, True)(0), Label).Text = "Er00"
DirectCast(Me.Controls.Find("Button" & Bindex, True)(0), Button).Text = "Er00"
End If
If SampleFlag = 2 Then 'sample count error
DirectCast(Me.Controls.Find("Label" & Bindex, True)(0), Label).Text = IncSamp
DirectCast(Me.Controls.Find("Button" & Bindex, True)(0), Button).Text = IncSamp
End If
If SampleFlag = 0 Then 'sample good
If SendMyAvg <> 0 Then
SendMyAvg = Math.Round(SendMyAvg, 2)
' MessageBox.Show("Button" & Bindex & " / " & SendMyAvg)
DirectCast(Me.Controls.Find("Label" & Bindex, True)(0), Label).Text = SendMyAvg
DirectCast(Me.Controls.Find("Button" & Bindex, True)(0), Button).Text = SendMyAvg
End If
End If
Next
End Sub
Private Sub CollectSample(ByVal Samplefile As String) 'call realterm, close realterm
NtBeep(500, 200) 'f,d
'http://www.dotnetperls.com/process-vbnet
Dim p As New ProcessStartInfo
p.FileName = "C:\Program Files (x86)\BEL\Realterm\realterm.exe"
p.Arguments = "C:\Program Files (x86)\BEL\Realterm\realterm.exe Baud=4800 Data=7E2 Port=" & USBPort & " timestamp=4 capfile=C:\IMAX_Ware_V2\LS100Cap\""" & targetName & """ capsecs=35 capture=1 Sendfile=""" & sourceName & """ Senddly=3000 Sendrep=10 CapQuit"
p.WindowStyle = ProcessWindowStyle.Hidden
Dim myProcess As Process = System.Diagnostics.Process.Start(p)
myProcess.WaitForExit()
myProcess.Close()
End Sub
I have the following sub
Public Sub Transfer()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim Searching_Date As String
Dim Name As String
Dim Presente As Boolean
Dim Foto_Presente As Boolean
For i = 0 To CDIi - 1
Searching_Date = Image_Date(Camera_Day_Images(i))
Name = Replace(Camera_Day_Images(i), Camera & Path_in_Camera & "\", "")
Presente = False
j = 0
While (Not Presente And j <= PCi)
If (Path & "\" & Right_Date(Searching_Date)) = PC_Directory(j) Then
Presente = True
Else
Presente = False
End If
j = j + 1
End While
If Presente = True Then
Foto_Presente = False
k = 0
List_PC_Day_Images(Path & "\" & Right_Date(Searching_Date))
While (Not Foto_Presente And k <= PDIi)
If (Path & "\" & Right_Date(Searching_Date) & "\" & Name) = PC_Day_Images(k) Then
Foto_Presente = True
Else
Foto_Presente = False
End If
k = k + 1
End While
If Foto_Presente = True Then
Else
My.Computer.FileSystem.CopyFile(Camera & Path_in_Camera & "\" & Name, Path & "\" & Right_Date(Searching_Date) & "\" & Name)
PC_Day_Images(PDIi) = Path & "\" & Right_Date(Searching_Date) & "\" & Name
PDIi = PDIi + 1
End If
Else
My.Computer.FileSystem.CreateDirectory(Path & "\" & Right_Date(Searching_Date))
My.Computer.FileSystem.CopyFile(Camera & Path_in_Camera & "\" & Name, Path & "\" & Right_Date(Searching_Date) & "\" & Name)
End If
Next
Principale.LFine.Text = "Tutte le tue foto sono state trasferite con successo"
Principale.Button1.Enabled = False
End Sub
It copies any photos from my device to my computer. So if I have a lot of photos It can take several time and I want to notify this. In fact I change the text in the label, than I call the Sub and finally rechange the label.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
LFine.Text = "attendere prego..."
Transfer()
LFine.Text = "Operazione completata con successo"
End Sub
But the results are that Transfer () starts and just after he finished changing the label.
Why??? How can I fix this problem??
Thank you.
After LFine.Text = "attendere prego..." add this line:
LFine.Update()
See https://msdn.microsoft.com/en-us/library/vstudio/system.windows.forms.control.update(v=vs.100).aspx
Wrap the call to tranfers() in an if statement
Change your Sub to a Function,
Public Function Transfer() As Boolean
...
then
If tranfers() = true then
LFine.Text = "Operazione completata con successo"
End if
That is because your process is a blocking process. The label is "updated" but the form is redrawn only after the whole process ends. Others have suggested to use Application.DoEvents() or LFine.Update, but the best way to do what you want is to make your process parallel.
You could use a BackgroundWorker for this:
Imports System.ComponentModel
Dim bgw As New BackgroundWorker
In the Load event of your form...
AddHandler bgw.DoWork, AddressOf bgw_DoWork
AddHandler bgw.RunWorkerCompleted, AddressOf bgw_RunWorkerCompleted
And then set your code like this...
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
LFine.Text = "attendere prego..."
bgw.RunWorkerAsync()
End Sub
Private Sub bgw_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim Searching_Date As String
Dim Name As String
Dim Presente As Boolean
Dim Foto_Presente As Boolean
For i = 0 To CDIi - 1
Searching_Date = Image_Date(Camera_Day_Images(i))
Name = Replace(Camera_Day_Images(i), Camera & Path_in_Camera & "\", "")
Presente = False
j = 0
While (Not Presente And j <= PCi)
If (Path & "\" & Right_Date(Searching_Date)) = PC_Directory(j) Then
Presente = True
Else
Presente = False
End If
j = j + 1
End While
If Presente = True Then
Foto_Presente = False
k = 0
List_PC_Day_Images(Path & "\" & Right_Date(Searching_Date))
While (Not Foto_Presente And k <= PDIi)
If (Path & "\" & Right_Date(Searching_Date) & "\" & Name) = PC_Day_Images(k) Then
Foto_Presente = True
Else
Foto_Presente = False
End If
k = k + 1
End While
If Foto_Presente = True Then
Else
My.Computer.FileSystem.CopyFile(Camera & Path_in_Camera & "\" & Name, Path & "\" & Right_Date(Searching_Date) & "\" & Name)
PC_Day_Images(PDIi) = Path & "\" & Right_Date(Searching_Date) & "\" & Name
PDIi = PDIi + 1
End If
Else
My.Computer.FileSystem.CreateDirectory(Path & "\" & Right_Date(Searching_Date))
My.Computer.FileSystem.CopyFile(Camera & Path_in_Camera & "\" & Name, Path & "\" & Right_Date(Searching_Date) & "\" & Name)
End If
Next
End Sub
Private Sub bgw_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
Principale.LFine.Text = "Tutte le tue foto sono state trasferite con successo"
Principale.Button1.Enabled = False
End Sub
Just make sure you don't access any control of your form inside bgw_DoWork method.