Move file after processing - vb.net

I have the following loop which works accept for the move file part
For Each foundFile As String In My.Computer.FileSystem.GetFiles(dir, FileIO.SearchOption.SearchTopLevelOnly, "*.csv")
''If (Not String.IsNullOrEmpty(lastFile)) Then
''File.Move(Path.GetFullPath(lastFile), (dir + "/processed/"))
''End If
Dim oTimer As New System.Diagnostics.Stopwatch
oTimer.Start()
Dim tblName = Path.GetFileNameWithoutExtension(foundFile)
Dim numbers() As Char = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
tblName = tblName.TrimEnd(numbers)
''analyze table name, call method for either insert or append
cmd.Parameters.Add(New SqlParameter("#tblName", tblName))
''this command should check the table to exist first, but need to add if
cmd.ExecuteNonQuery()
retRecCnt += insertRows(conString, foundFile, tblName)
cmd.Parameters.Clear()
lastFile = foundFile
''
Next
It properly exports the CSV file to the database table and moves on to the next file. but when the move command is called I get the following error:
System.IO.IOException was unhandled
HResult=-2147024864
Message=The process cannot access the file because it is being used by another process.
Source=mscorlib

Related

How do I change a looping input to one that accepts a list or table input from access?

I am attempting update routinely used code designed by a previous employee to make it more efficient.
The code works fine but prompts the user to input a "PlateID" with every loop. This was developed when a worker would only have one or two plates to input , now we have people inputting upwards of 30-40, which is killing productivity (not only a huge risk for user error).
What I would like to is instead of querying the user for PlateID each time, instead take a list input or even just take the list from a table.
The purpose of this code is to taken Plate information we receive from lab equipment and transform it into a format we can use in-lab.
I have tried changing the qrySamplesOnPlates query to have a criteria that is a list but it seems to get overwritten by the code, even if I comment out the input box. I know this is probably really easy its just doing my head in.
Sub PCRSplit(OutputLoc As String)
Dim objConn As New ADODB.Connection
Dim objCmd As New ADODB.Command
Dim LabID As String
Dim db As DAO.Database
Dim tblRst As DAO.Recordset
Dim PlateID As Integer
Dim Rst1 As New ADODB.Recordset
Dim AryWellLetter, AryLayoutFullPlate, AryLayoutWell, SampleID, WellNumber, RowNumber, WellLetter
Dim varAnswer As Variant
Dim exRst As ADODB.Recordset
Dim UserName As String
Dim ProjectName As String
Dim ExperimentName As String
Dim Manifest As String
Dim manRst As ADODB.Recordset
Dim ControlPos As String
Dim Counter As Integer
If objConn = "" Then
Set objConn = GetNewConnection
objCmd.ActiveConnection = objConn
End If
On Error GoTo errHandler
'delete everything out of the table that sample ID's get written to
objCmd.CommandText = "qrySamplesOnPlatesDELETE"
objCmd.CommandType = adCmdStoredProc
objCmd.Parameters.Refresh
objCmd.Execute
'LabID is a criteria for the query that pulls out plate information
LabID = InputBox("Enter Lab")
'open the table that sample ID's get written to
Set db = CurrentDb
Set tblRst = db.OpenRecordset("SamplesOnPlates")
Do
'PlateID is a criteria for the query that pulls out plate information
PlateID = InputBox("Enter Plate")
'run the query to pull download pre-formatted plate information and assign it to the variable Rst1
objCmd.CommandText = "qrySamplesOnPlates"
objCmd.CommandType = adCmdStoredProc
objCmd.Parameters.Refresh
Set Rst1 = objCmd.Execute(, Array(LabID, PlateID))
'whole bunch of data transformation lines (dont worry about this)
For i = 1 To 96
AryWellLetter = Array("PlaceHolder", "A", "B", "C", "D", "E", "F","G", "H", "I", "J", "K", "L", "M", "N", "O", "P")
AryLayoutFullPlate = Split(Rst1.Fields("Layout").Value, "][")
AryLayoutWell = Split(AryLayoutFullPlate(i), ",")
SampleID = AryLayoutWell(2)
ControlPos = AryLayoutWell(3)
If Len(AryLayoutWell(1)) = 1 Then WellNumber = "0" & AryLayoutWell(1) Else WellNumber = AryLayoutWell(1)
RowNumber = AryLayoutWell(0)
WellLetter = AryWellLetter(RowNumber)
With tblRst
.AddNew
.Fields("SampleID") = SampleID
.Fields("Well") = WellLetter & WellNumber
.Fields("PlateID") = PlateID
.Fields("LabID") = LabID
.Fields("ControlPos") = ControlPos
.Update
End With
Next
'this will loop through the above code and continue to add new plates to the SamplesOnPlates table until the user clicks No button
varAnswer = MsgBox("Do you want to enter another plate?", vbYesNo)
Loop Until varAnswer = 7
tblRst.Close
'more transformation after this that isnt relevant
PlateID = InputBox("Enter Plate") is the key area in looking to change

CSV string is being trimmed while importing with OleDb

I am reading csv file with oledb mechanism. My main issue is that the string values inside csv while reading are being trimmed (both: at the beggining and and the end with white spaces). I have some specific data in csv file which needs to have such white spaces in only some cases - that's why i cannot handle that after being processed. It has to be done with the convertion.
Unfortunatelly it has to be done with oledb and vb.net as our complex mechanism is based on those technologies.
Is that possible to find a hack or workaround that oledb will not trim my strings?
Below is my code, actual results and expected:
csv file:
Column1|Column2|Column3|Column4
Text1 | Text2| Text3 |Text4
schema.ini
[test.csv]
Format=Delimited(|)
Col1=Column1 Text
Col2=Column2 Text
Col3=Column3 Text
Col4=Column4 Text
Code
Private conn As New OleDbConnection
Private cmd As New OleDbCommand
Private myAccessDataReader As OleDb.OleDbDataReader = Nothing
Sub Main()
Try
Dim dirInfo As String = "C:\csv"
If conn.State = ConnectionState.Open Then
conn.Close()
End If
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & dirInfo & ";Extended Properties=""Text;HDR=Yes;"";"
conn.Open()
cmd = New OleDbCommand("SELECT * From [test.csv]", conn)
myAccessDataReader = cmd.ExecuteReader()
If myAccessDataReader.HasRows Then
myAccessDataReader.Read()
End If
Console.WriteLine("|" + myAccessDataReader.Item("Column1") + "|")
Console.WriteLine("|" + myAccessDataReader.Item("Column2") + "|")
Console.WriteLine("|" + myAccessDataReader.Item("Column3") + "|")
Console.WriteLine("|" + myAccessDataReader.Item("Column4") + "|")
Console.ReadKey()
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
Actual Results:
|Text1|
|Text2|
|Text3|
|Text4|
Expected Results:
|Text1 |
| Text2|
| Text3 |
|Text4|
Ps. I have tried with different settings in schema.ini: encoding, MaxScanRows, fixed width, but nothing helped.
I guess there is a general issue with trailing spaces when dealing with database: some char data types use spaces to fill the rest of the characters. For MSSql there is an option ANSI PADDING which you can turn ON/OFF, but I don't see a way to set that for Microsoft JET Engine which we use for CSV files; we support both oledb and odbc and this issue exists for both.
So, the answer is you can't. Trailing spaces will be always removed when you import data from a CSV data source, no matter if you define text/char/memo data type for your columns (e.g. using schema.ini) or enclose strings into double quotes. You can put some special character (non-space) in the end, after space(s), such as tab, for instance.
microsoft website
Try this out.....but there's no guarantee since I haven't put any error handling....
Function ReadCSVToTable(ByVal Schema As String) As DataTable
Dim file As New StreamReader("C:\dump\" & Schema)
Dim CSVName As String = file.ReadLine()
CSVName = Strings.Mid(CSVName, 2, CSVName.Length - 2)
Dim Delimiter As String = file.ReadLine
Delimiter = Strings.Mid(Delimiter, Strings.InStr(Delimiter, "(") + 1, Delimiter.Length - Strings.InStr(Delimiter, ")") + 1)
Dim Buffer As String = ""
Dim xtable As New DataTable
xtable.TableName = CSVName
'create table
Do
Buffer = file.ReadLine
Dim xCol As New DataColumn
With xCol
.ColumnName = Buffer.Split("=")(0)
.Caption = Buffer.Split("=")(1).Split(" ")(0)
Select Case Buffer.Split("=")(1).Split(" ")(1).ToLower
Case "text"
.DataType = GetType(String)
Case "integer"
.DataType = GetType(Integer)
Case "decimal"
.DataType = GetType(Decimal)
Case "boolean"
.DataType = GetType(Boolean)
Case Else
.DataType = GetType(String)
End Select
End With
xtable.Columns.Add(xCol)
Loop Until file.EndOfStream = True
file.Close()
file.Dispose()
'Fill the table
file = New StreamReader("C:\dump\" & CSVName)
'skip header
Buffer = file.ReadLine
Do
Buffer = file.ReadLine
Dim xCol(xtable.Columns.Count - 1)
Dim xCount As Integer = 0
For Each tCol As DataColumn In xtable.Columns
Select Case tCol.DataType
Case GetType(String)
xCol(xCount) = Convert.ToString(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case GetType(Integer)
xCol(xCount) = Convert.ToInt64(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case GetType(Decimal)
xCol(xCount) = Convert.ToDecimal(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case GetType(Boolean)
xCol(xCount) = Convert.ToBoolean(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case Else
xCol(xCount) = Convert.ToString(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
End Select
xCount = xCount + 1
Next
xtable.Rows.Add(xCol)
Loop Until file.EndOfStream = True
file.Close()
file.Dispose()
Return xtable
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim CSVTable As DataTable = ReadCSVToTable("schema.ini")
End Sub

VBNet Reading csv file - separating column in a row - comma delimited

This has been bugging me for a week and i do not see any other way. We have only been taught record data structures which is basic, FileOpen, WriteLine and etc. but i read MSDN and StreamWriter/Reader looks much more promising. This is an assignment/coursework and its essential for practically all parts of the program.
All i want to do is read line by line separating fields by a comma and define it as a variable. It would also help to be able to read the line without the quotes "", because right now when i read a password out with LineInput it reads it entirely "pass".
Private Sub StudentLogin()
Dim Filename As New StreamWriter("" & Register.StudentDirectory & "" & Username & ".txt")
Dim str As String = "This"
Dim lines() As String = str.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
For Each line As String In lines
Dim columns() As String = line.Split(","c)
Firstname = columns(0)
Surname = columns(1)
Password = columns(2)
ClassID = columns(3)
Next
MessageBox.Show("" & ClassID & " " & Password & "")
End Sub
Text file:
"cem","polat","pass","class"
I just want to read the file - then each line, row by row, defining each column field which is in C:/Spellcheck/data/accounts/students/+filename+ and define a few variables.

VB.NET read only some cells for each row from csv file

I have a csv file that has the following structure :
id,name,adress,email,age
1,john,1 str xxxx,john#gmail.com,19
2,mike,2 bd xxxx,mike#gmail.com,21
3,jeana,1 str ssss,jeana#gmail.com,18
.......................
.......................
What I would like to do is to read the csv file, skip the first line (contains headers) and extract the 2nd, 3rd and 4th data from each row and populate a datagridview.
This is the code I'm using however it brings me all the csv content :
DataGridView1.ColumnCount = 4
DataGridView1.Columns(0).Name = "ID"
DataGridView1.Columns(1).Name = "NAME"
DataGridView1.Columns(2).Name = "ADRESS"
DataGridView1.Columns(3).Name = "AGE"
Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser _
(openFile.FileName)//the csv path
'Specify that reading from a comma-delimited file'
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
With DataGridView1.Rows.Add(currentRow) 'Add new row to data gridview'
End With
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
End Try
End While
End Using
So can someone show me how to do that?
Thanks.
It could be simple as reading the first line and discard it, Then start to read the real data from your file
Using MyReader As New TextFieldParser(openFile.FileName)
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
' Read the first line and do nothing with it
If Not MyReader.EndOfData Then
currentRow = MyReader.ReadFields()
End If
While Not MyReader.EndOfData
Try
' Read again the file
currentRow = MyReader.ReadFields()
DataGridView1.Rows.Add(currentRow(1), currentRow(2),currentRow(3))
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
End Try
End While
End Using
EDIT Seeing your comment below then I have changed the line that add the row to add only the strings at position 1,2 and 3. This of course is different from the columns added to the DataGridView. It is not clear if you want to change these columns to contains only these 3 fields. If you still want the column for ID and AGE in the grid you could change the Add to
DataGridView1.Rows.Add("", currentRow(1), currentRow(2),currentRow(3), "")

VB2010 Mutli-dimensional Arrays, mind-block

So I am trying to make the card game WAR in visual basic 2010. I have the following code and I kind of know what I need to do next but I just can't get to the next step.
Public Class form1
'throws an error unless this is the first class in the file
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'click the button currently labled "loop"
Dim Cards() As String = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack"} 'spades,hearts/diamonds,clubs
Dim Values() As String = {"11", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"} 'faces is a term meaning a card that depicts a person
Dim suits() As String = {"H", "D", "C", "S"}
Dim p1deck()() As String '
'first (0) is the number of the array
'second(0) is the string
p1deck(0)(0) = "Ace"
p1deck(0)(1) = "11"
p1deck(0)(2) = "Hearts"
TextBox1.Text = p1deck(0)(0) & " of " & p1deck(0)(2)
'Cards.ToList(). add/removeAt
End Sub
End Class
You are not Initializing your p1deck array.
Try something like this:
Dim p1deck(2, 3) As String
p1deck(0, 0) = "Ace"
p1deck(0, 1) = "11"
p1deck(0, 2) = "Hearts"
TextBox1.Text = p1deck(0, 0) & " of " & p1deck(0, 2)