VB.NET Writing MSSQL data to DBF format - sql

I am trying to export MS-SQL data to DBF format.
Is there anyway to achieve this as I can't find any solution to this?
I am using SQL Server 2008 Express R2 in Visual Studio 2008.
Thanks in advance!

Try this link:
https://www.pcreview.co.uk/threads/export-data-from-mssql-to-dbf-using-vb-net.1239926/
Hi,
This is not as easy as you might suppose. I do it frequently, but I first
have to create the structure of the .dbf table I want to generate and then I
place it with an _ in the name in a designated subdirectory. The reason I
have to do this is because the odbc driver for ado .net is limited in the
datatypes it will create, so I can't very well fashion the .dbf file
directly inside .net.
The function below does the rest - it turns a given dataset into a .dbf
file, as you are trying to do; I simply pass the dataset, the .dbf name and
the number of columns to it.
Public Function tabletodbf(ByVal mtable As DataSet, ByRef mdbf As String, ByVal numcols As Integer) As Integer
' suppositions: the dbf file is in f:\imcapps\dbffiles; also, there is
' an empty of it with a _ at the end of the filename; also, we are working
' with dbf files exclusively in f:\imcapps\dbffiles; also, the table and
' the dbf have to have the exact same structure and in the same column #
' sequence; also, if the _ causes
' the file name to be too large, this probably won't work, so I have to
' ensure this doesn't happen
' signature:
' dim funcs as new imcfunctionlib.functions
' dim xint as integer
' xint = funcs.tabletodbf(dspslips, "netcsv.dbf", 5)
' xint = funcs.tabletodbf(dsletsumtt2, "letsumtt.dbf", 27)
tabletodbf = 0
Dim oconn_ As New SqlConnection("data source=d5z0071;database=imc;integrated security=sspi;")
Dim oconn_d_ As New OdbcConnection("Driver={Microsoft dBase Driver (*.dbf)};UID=admin;usercommitsync=yes;threads=3;statistics=0;safetransaction s=0;pagetimeout=5;maxscanrows=8;maxbuffersize=2048;FIL=dBaseIV;DriverID=533;deleted=0;defaultdir=f:\imcapps\dbffiles;dbq=f:\imcapps\dbffiles;collatingsequence=ascii;")
oconn_.Open()
oconn_d_.Open()
Dim path As String = "f:\imcapps\dbffiles\" & mdbf
Dim underscorename As String
underscorename = Mid(mdbf, 1, mdbf.Length - 4) & "_.dbf"
Dim fi As FileInfo = New FileInfo(path)
If fi.Exists = True Then
Kill("f:\imcapps\dbffiles\" & mdbf)
End If
FileCopy("f:\imcapps\dbffiles\" & underscorename, "f:\imcapps\dbffiles\" & mdbf)
' always save an empty file with _ as a convention
Dim da_d As New OdbcDataAdapter("select * from f:\imcapps\dbffiles\" & mdbf, oconn_d_)
Dim ds_d As New DataSet("_d")
da_d.Fill(ds_d, "_d")
Dim commandbuilder_ds_d As OdbcCommandBuilder = New OdbcCommandBuilder(da_d)
Dim i As Integer
Dim irow, mrow_d As DataRow
For Each irow In mtable.Tables(0).Rows
mrow_d = ds_d.Tables(0).NewRow()
For i = 0 To numcols - 1
mrow_d(i) = irow(i)
Next
ds_d.Tables("_d").Rows.Add(mrow_d)
Next
Try
da_d.Update(ds_d, "_d")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
oconn_.Close()
oconn_d_.Close()
tabletodbf = 1
End Function
I am not so sure... you may try if it works.

Related

How can I ignore a new line character when reading CSV file in VB.NET?

I wrote a utility in VB.NET that reads an input CSV file, does some processing (specifically it ignores the first 5 lines of the input file and replaces them with a header row saved in another file) and writes the information from the input file into a new output CSV file.
Where my program fails is when the input data includes new line characters within one column value within the CSV.
I would like to ignore the new line character within a CSV data row when I load it into my string array.
Here is my code (its embedded in a form)
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim incsvPath = strFileName
Dim outcsvPath = fi.DirectoryName & "\" & outfilename
Dim headerPath = fi.DirectoryName & "\ACTIVITY_HISTORY_HEADER.csv"
Dim fileP As String = incsvPath
Dim fileheader As String = headerPath
Dim CSVheaderIn As New ArrayList
Dim CSVlinesIn As New ArrayList
Dim CSVout As New List(Of String)
CSVheaderIn.AddRange(IO.File.ReadAllLines(fileheader))
CSVlinesIn.AddRange(IO.File.ReadAllLines(fileP))
messageTB.AppendText(vbCrLf & vbCrLf)
For Each line As String In CSVheaderIn
Dim nameANDnumber As String() = line.Split(",")
messageTB.AppendText("csv file header row = " & line & vbCrLf & vbCrLf & "csv file contents follow ..." & vbCrLf)
CSVout.Add(line)
Next
Dim mySubAL As ArrayList = CSVlinesIn.GetRange(5, CSVlinesIn.Count - 5)
For Each line As String In mySubAL 'CSVlinesIn
messageTB.AppendText(line & vbCrLf)
CSVout.Add(line)
Next
IO.File.WriteAllLines(outcsvPath, CSVout.ToArray)
End Sub
This is fairly hard work actually; it'll be easier to use a library that knows how to read and write CSV with newlines in the data than roll your own - not saying you couldn't, but it's a wheel that has already been invented so why do it again?
I used Steve Hansen's Csv - right click your project in solution explorer, choose Manage Nuget Packages, click Browse, Search csv, install the right one
Imports System.Text
Imports Csv
Imports System.IO
Module Module1
Sub Main(args As String())
'open the headers file
Using hIn = File.OpenText("C:\temp\h.csv")
'setup instruction to the csv reader with headersabsent flag so we can get the first line as data
Dim hOptions = New CsvOptions With {.HeaderMode = HeaderMode.HeaderAbsent}
'take the first line into an array - these are our headers
Dim headers = CsvReader.Read(hIn, hOptions)(0).Values
'open the data file,
Using fIn = File.OpenText("C:\temp\a.csv")
'setup instruction for the reader to skip 5 rows, treat first row as data, and allow newlines in quoted fields
Dim fOptions = New CsvOptions With {.RowsToSkip = 5, .HeaderMode = HeaderMode.HeaderAbsent, .AllowNewLineInEnclosedFieldValues = True}
Using fOut = File.CreateText("C:\temp\a_out.csv")
'convert the ICsvLine rows in the reader to rows of String() that the writer will accept, and write them under the headers
CsvWriter.Write(fOut, headers, CsvReader.Read(fIn, fOptions).Select(Function(line) line.Values))
End Using
End Using
End Using
End Sub
End Module
You don't have to use this lib to read the headers; you could just file.ReadText().ReadLine().Split(","c) it
If you want to perform per-line processing on the elements, do this:
CsvWriter.Write(fOut, headers, CsvReader.Read(fIn, fOptions).Select(Function(line) ProcessLine(line.Values)))
...
Function ProcessLine(input As String()) As String()
'Note: If(input(8), "") returns input(8) unless it is nothing in which case "" is returned instead
If If(input(8), "").Length > 10 Then input(8) = input(8).Remove(10) 'Trim if over 10
If If(input(14), "").Length > 10 Then input(14) = input(14).Remove(10)
Return input 'Always return
End Function

Export data to Excel file from SQL Server database

I want to create a program that can export data from sql server database to
excel file and the file name must be auto generated and auto incremented.
I query data from server using date time picker as below:
`command.CommandText = ("Select * from ComponentCheckerSystem where
Last_Update between #FromDate AND #ToDate;")
command.Parameters.Add("#FromDate", SqlDbType.Date).Value =
DateTimePicker1.Value.Date
command.Parameters.Add("#ToDate", SqlDbType.Date).Value =
DateTimePicker2.Value.Dat`
'set final path
Dim fileName As String = "\Summary of Operator Scan Wrong Items"
+ ".xls" 'just set the file Name
Dim finalPath = f.SelectedPath + fileName
txtPath.Text = finalPath
oSheet.Columns.AutoFit()
Please help me to make a function to auto generate file name.
thank you.
To create a place in Settings for your data:
1.Project Menu > Properties (all the way at the bottom)
2. Choose the Settings tab (on the left)
3. File out the boxes Name: LastFile, Type: Integer, Scope: User Value: will be set for you to 0
Actually, you could store your LastFile variable value in a text file or a database but I chose App.config for convenience.
You already know how to set your directory and the following code will get you a new file name.
Private Function GetNewFileName() As String
Dim FileSuffix As Integer = My.Settings.LastFile
FileSuffix += 1
Dim NewFileName As String = String.Format("\Summary of Operator Scan Wrong Items{0}.xls", FileSuffix)
My.Settings.LastFile = FileSuffix
Return NewFileName
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim file As String = GetNewFileName()
Debug.Print(file)
End Sub

Can I compute the name of a variable in VB.net

I want to know if it is possible to compute the name of a variable in VB.net. I need to open a bunch of text files at runtime. The exact number will be variable. I wanted to do something along the lines of:
For j = 1 to Filecount
Dim Filename As String = "File"&j
Dim File & j As New System.IO.StreamWriter(Filename)
Next
When I tried this, VB.net said it didn't like it. Is this possible?
I think you would be better off using a dictionary, which would allow you to get back to the appropriate stream writer using the filename later:
Dim fileDictoinary As New Dictionary(Of String, System.IO.StreamWriter)
For j = 1 To Filecount
Dim Filename As String = "File" & j
fileDictoinary.Add(Filename, New System.IO.StreamWriter(Filename))
Next
Then at a later time you can access the streamwriter using the filename in the dictionary:
Dim file4StreamWriter = fileDictoinary("File4")
file4StreamWriter.Write(True)

skip first row when reading excel CSV file

I found how to do this in several languages but not in .net (specifically vb.net). I am using OLeDbCommand to read both CSV and Excel files. In case of Excel I can skip first row and select second row onwards by specifying a range of cells. But in case of CSV, I am not sure how to do it.
Current code looks like:
Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM [" + Path.GetFileName(FileName) + "]", cn)
Here we give the file, not the sheet. So I am bit stuck.
From my experience reading a text file like this is very restrictive. It only allows you to read the whole file, because you can't specify a table name. You might be better of reading each line and making table rows and adding them to a table. If the first row is headers you can use that to make the columns, otherwise hard code the columns.
Here's a simple little method that fills a datatable with the data from a .csv file, that you should be able to use:
Private Sub GetData(ByRef dt As DataTable, FilePath As String, Optional ByVal Header As Boolean = True)
Dim Fields() As String
Dim Start As Integer = CInt(Header) * -1
If Not File.Exists(FilePath) Then
Return
End If
dt.Clear()
Dim Lines() As String = File.ReadAllLines(FilePath)
If CBool(Start) AndAlso dt.Columns.Count = 0 Then
Lines(0) = Lines(0).Replace(Chr(34), "")
For Each h As String In Lines(0).Split(",")
dt.Columns.Add(h)
Next
End If
For I = Start To Lines.Count - 1
Fields = Lines(I).Split(",")
dt.Rows.Add(Fields)
Next
End Sub

SQL.REQUEST Excel function Alternative? Create one with VBA?

I am looking to execute SQL SELECT statement inside a single cell in Excel, using other cells as inputs to the SELECT statement. After some searching, I found that the sql.request function would have done exactly what I'm looking for. However, that function was deprecated in after 2002, and I'm running Excel 2007 and 2010 here at work. Citation
I have tried to create a Macro / VBA script that does the same thing, but haven't been able to get very far with it. I do all my programming in LabVIEW, Mathematica, and SQL; I have no idea what's going on in VBA. This is what I've managed to come up with:
Sub Test2()
' Declare the QueryTable object. I'm not actually sure why this line is here...
Dim qt As QueryTable
' Set up the SQL Statement
sqlstring = "SELECT `Substrate ID` FROM temp_table WHERE `id`=" & Range("A1").Value
' Set up the connection string, reference an ODBC connection
connstring = "ODBC;DSN=OWT_x64;"
' Now implement the connection, run the query, and add
' the results to the spreadsheet
With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A22"), Sql:=sqlstring)
.Refresh BackgroundQuery:=False
End With
End Sub
There are three primary issues with the above code:
This code returns the column ID ("Substrate ID") in cell A22, and the result of the SQL query in cell A23. I only want the result, and I only want it in cell A22. All queries are forced to return only 1 row and 1 column.
I don't know how to make it so that the output cell, A22, is whatever cell is active when the script is run. Also, the input cell, A1, should be the cell directly to the left (column-1) of the active cell.
I don't know how to turn this into an Excel function
=sql.request(connection_string,[output_ref],[driver_prompt],[query_text],[col_names_logical])
which is my final goal. This way, I can give this code to others at my company and they can easily use it.
The connection is a ODBC connection to a MySQL 5.6 database. The query is pretty simple, and along the lines of:
SELECT column FROM table WHERE id=excel_cell_value
as you can see from the VBA code that I have.
Currently, I run a query in a different Excel worksheet that returns all rows of the "id" and "Substrate ID" columns and then run VLOOKUP to find the item of interest. This is starting to become an issue, as our database size is growing quite fast.
So, I ask:
How can I get rid of the column ID in the result?
How can I turn this into a custom excel function? I've looked at Office.com and it doesn't seem too difficult, but I need a working script first.
-OR- Has anyone already made a custom function that they're willing to share?
Thanks!
EDIT: Managed to get something working thanks to Tim's link.
Function SQLQuery(sqlString As String, connString As String, Optional TimeOut As Integer) As String
SQLQuery = Error 'Assume an error happened
Dim conn As ADODB.Connection
Dim record As ADODB.Recordset
Set conn = New ADODB.Connection
conn.ConnectionString = connString
conn.Open
Set record = New ADODB.Recordset
If TimeOut > 0 Then
conn.CommandTimeout = TimeOut
End If
record.Open sqlString, conn
Dim cols As Long
Dim i As Long
cols = record.Fields.Count 'Count how many columns were returned
If Not record.EOF Then 'Put results into comma-delimited string
record.MoveFirst
s = ""
If Not record.EOF Then
For i = 0 To cols - 1
s = s & IIf(i > 0, ",", "") & record(i)
Next i
End If
End If
SQLQuery = s
End Function
However, it's quite slow. Any ideas on how to speed it up?
Here's a quick test of caching the connection. On a test worksheet with 100 lookups it reduced calculation time from about 18 sec to about 0.5 sec
Remember though it will keep a connection open until you close Excel (or the VB environment gets reset).
If you want to test the difference in your environment, you can comment out the marked line (don't forget to also press the "stop" button in the VBE to clear the static variables).
Function SQLQuery(sqlString As String, connString As String, _
Optional TimeOut As Integer) As String
Static cs As String
Static conn As ADODB.Connection
SQLQuery = Error 'Assume an error happened
Dim s
If conn Is Nothing Or connString <> cs Then
Set conn = New ADODB.Connection
conn.ConnectionString = connString
conn.Open
If TimeOut > 0 Then conn.CommandTimeout = TimeOut
cs = connString '###comment this out to disable caching effect
End If
Dim record As New ADODB.Recordset
record.Open sqlString, conn
Dim cols As Long
Dim i As Long
cols = record.Fields.Count 'Count how many columns were returned
If Not record.EOF Then 'Put results into comma-delimited string
record.MoveFirst
s = ""
If Not record.EOF Then
For i = 0 To cols - 1
s = s & IIf(i > 0, ",", "") & record(i)
Next i
End If
End If
SQLQuery = s
End Function