I have the following array that contains ticker symbols: Public Shared tickerArray() As String = {"GOOG", "AAPL", "V", "MSFT"}. I need to use this loop: For Each tickerValue In Form1.tickerArray to load the csv file for each ticker symbol into one large table in Microsoft Access. The csv files are located at "http://ichart.yahoo.com/table.csv?s=" & tickerValue. I also need the respective ticker symbol to be loaded into each line of the table that is imported from the csv file in order to make each line unique. So the columns in the database should be: "Ticker, Date, Open, High, Low, Close, Volumne & Adj Close".
I've found information about loading a local csv file into Access but I can't seem to figure out how to load csv files from the internet into Access through vb.net.
Also, I will need to update this table frequently so I need to only insert new unique lines from the csv file. No duplicates.
Any suggestions? Thanks!
UPDATE:
Here is the code I have so far.
Imports System.Data
Imports System.Data.OleDb
Imports System.Net
Imports System.IO
Public Class Form1
Public Shared tickerArray() As String = {"GOOG", "AAPL", "V", "MSFT"}
Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
Dim myConnection As OleDbConnection
Dim DBpath As String =
Dim sConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & DBpath & ";Persist Security Info=True"
myConnection = New OleDbConnection(sConnectionString)
myConnection.Open()
Dim strURL As String
Dim strBuffer As String
For Each tickerValue In Form1.tickerArray
'Creates the request URL for Yahoo.
strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
strBuffer = RequestWebData(strURL)
'Create array.
Dim sReader As New StringReader(strBuffer)
Dim List As New List(Of String)
Do While sReader.Peek >= 0
List.Add(sReader.ReadLine)
Loop
Dim lines As String() = List.ToArray
sReader.Close()
For Each Line In lines.Skip(1)
MsgBox(Line)
Dim myInsert As String = TextToInsert(Line, tickerValue)
Dim cmd As New OleDbCommand(myInsert, myConnection)
cmd.ExecuteNonQuery()
Next
Next
End Sub
Function TextToInsert(ByVal inputString As String, ByVal ticker As String)
Dim Dt As String = inputString.Split(",")(0).Trim
Dim Open As String = inputString.Split(",")(1).Trim
Dim High As String = inputString.Split(",")(1).Trim
Dim Low As String = inputString.Split(",")(1).Trim
Dim Close As String = inputString.Split(",")(1).Trim
Dim Volume As String = inputString.Split(",")(1).Trim
Dim Adj_Close As String = inputString.Split(",")(1).Trim
Dim SQLstr As String
SQLstr = "INSERT INTO Historical (Ticker, Date, Open, High, Low, Close, Volume, Adj Close) " & "VALUES (" & "'" & ticker & "','" & Dt & "','" & Open & "','" & High & "'," & "'" & Low & "','" & Close & "','" & Volume & "','" & Adj_Close & "'" & ")"
Return SQLstr
End Function
Private Function RequestWebData(ByVal pstrURL As String) As String
Dim objWReq As WebRequest
Dim objWResp As WebResponse
Dim strBuffer As String
'Contact the website
objWReq = HttpWebRequest.Create(pstrURL)
objWResp = objWReq.GetResponse()
'Read the answer from the Web site and store it into a stream
Dim objSR As StreamReader
objSR = New StreamReader(objWResp.GetResponseStream)
strBuffer = objSR.ReadToEnd
objSR.Close()
objWResp.Close()
Return strBuffer
End Function
End Class
I get error code "OleDBException was unhandled. Syntax error in INSERT INTO statement." at line cmd.ExecuteNonQuery() Please help!
you may use the System.Data.OleDb Namespace to define function to make insert into the db.
Something like (in a very rough way):
Dim myConnection As OleDbConnection
Dim sConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & DBpath & ";Persist Security Info=True"
myConnection = New OleDbConnection(sConnectionString)
myConnection.Open()
Then make a cycle on each line in the csv
Dim myInsert as String= functionTextToInsert(inputString)
Dim cmd As New OleDbCommand(myInsert, myConnection)
cmd.ExecuteNonQuery()
The functionTextToInsert(ByVal inputString as string) is a function that converts a line from the csv in a insert string: "max;min;vol" -> "Insert into MYTABLE (Column_01,Column_02,Column_03) VALUES (max,min,vol);"
Try this:
Writing large number of records (bulk insert) to Access in .NET/C#
I've never worked with DAO, so I can't be much help here, but...
if this MSSQL syntax works on MS ACCESS, use a command object and pass it a parameter containing your csv as a varchar(max), or similar access data type, which will the content of the CSV from your app:
BULK
INSERT mytable
FROM #myCSVstring
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
GO
Two things, the SO post states that DAO is a lot faster, and your terminators may be different, but I'd start with these.
I think the previous answers are unnecessarily complicated. All you need to do it send an XMLHTTP request. That fetches the CSV data as a string, which can then be parsed into a table.
Below is a VBA subroutine that does that. Documentation of where I found the techniques is in the code comments. I've run this in Access 2019, and it works.
The modifications of the data indicated in the question can be performed before or after inserting the data into the table.
Sub pImportOnlineCsvAsTable(sURL As String, sTableName As String, Optional sKey As String)
' Download a CSV file from the Internet and parse it into an Access table (all strings).
' Adapted from "www.stackoverflow.com/questions/52142757/vba-download-csv-from-a-link/#52175815"
' This shows how to download an online CSV file into an ADO stream, then save it as a local file.
' and "www.stackoverflow.com/questions/33860833/convert-adodb-binary-stream-to-string-vba/#33883789"
' This shows I don't need the stream, but can use the CSV data as a string and parse it into a table.
' Documentation on "XMLHTTP" object:
' "https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms760305(v=vs.85)"
Dim oWinHttpReq As Object
Dim oDB As Database
Dim sSQL As String, sCSVdata As String, _
asCSVrows As Variant, asCSVfields As Variant, _
nCSVrows As Long, nCSVfields As Integer, _
nCountRows As Long, nCountFields As Integer
Set oDB = CurrentDb()
Set oWinHttpReq = CreateObject("Microsoft.XMLHTTP")
oWinHttpReq.Open "get", sURL, False
oWinHttpReq.send
If oWinHttpReq.status = 200 Then
sCSVdata = oWinHttpReq.ResponseText
asCSVrows = Split(sCSVdata, Chr(10))
nCSVrows = UBound(asCSVrows) + 1
asCSVfields = Split(asCSVrows(0), ",")
nCSVfields = UBound(asCSVfields) + 1
sSQL = ""
For nCountFields = 0 To (nCSVfields - 1)
sSQL = sSQL & "[" & asCSVfields(nCountFields) & "] varchar(255)" & _
IIf(nCountFields = nCSVfields - 1, "", ", ")
Next
sSQL = "create table [" & sTableName & "] (" & sSQL & ");"
oDB.Execute (sSQL)
For nCountRows = 1 To (nCSVrows - 1)
asCSVfields = Split(asCSVrows(nCountRows), ",")
sSQL = ""
For nCountFields = 0 To (nCSVfields - 1)
sSQL = sSQL & """" & asCSVfields(nCountFields) & """" & _
IIf(nCountFields = nCSVfields - 1, "", ", ")
Next
sSQL = "insert into [" & sTableName & "] values (" & sSQL & ");"
oDB.Execute (sSQL)
Next
If sKey <> "" Then _
oDB.Execute "alter table [" & sTableName & "] add primary key ([" & sKey & "]);"
End If
Set oWinHttpReq = Nothing
Set oDB = Nothing
End Sub ' pImportOnlineCsvAsTable()
Related
I have a macro enabled Excel sheet in MAC where I have some data and want to export it to SQL Server. I am trying to truncate the target table first and then insert but my code is not working. The code needs to be working across both MAC and Windows. Please help.
Sub Export_Click()
Dim sqlstring As String
Dim connstring As String
Dim sLogin As String
Dim rng As Range
Dim defaultDate As String
Dim sql As String, bulkSql As String
Dim intImportRow As Integer
Dim Product, Resource As String
Dim name, address as String
'sLogin = "Uid=$;Pwd=$;"
'sqlstringfirma = "SELECT * from tableA"
connstring = "ODBC;DRIVER=SQL Server;SERVER=ServerIP;DATABASE=databse;UID=uid;PWD=pwd"
sql_trunc = "truncate table tableA"
sql_commit = "commit"
sql_query = "select * from table tableA"
With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A1"), sql:=sql_trunc)
.BackgroundQuery = False
'.Refresh
End With
intImportRow = 10
Do Until .Cells(intImportRow, 1) = ""
Product = .Cells(intImportRow, 1)
Resource = .Cells(intImportRow, 2)
sql_insert = "insert into tableA (name, address) values ('" & name & "', '" & address & "')"
With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A1"),
sql:=sql_insert)
.BackgroundQuery = False
.Refr
intImportRow = intImportRow + 1
Loop
End Sub
I am working on an existing database structure. The database has a field to store PDF/Word/Jpeg files as images. Unfortunately I cannot change the database field format.
I am able to successfully read the pdf stored as image and display the pdf file, but cannot get to insert the image in database. I tried different version from many sites, but could not get it to work.
Here is my current code
Dim sql As String
Dim da As New OleDb.OleDbDataAdapter
Dim sqlquery As New OleDb.OleDbCommand
Dim sqlconn As New OleDb.OleDbConnection
Try
sqlconn.ConnectionString = dbConnectStr1
sqlquery.Connection = sqlconn
sqlconn.Open()
For cnt1 = 0 To dgv1.Rows.Count - 1
Dim fInfo As New FileInfo(dgv1.Rows(cnt1).Cells(3).Value)
Dim numBytes As Long = fInfo.Length
Dim fStream As New FileStream(dgv1.Rows(cnt1).Cells(3).Value, FileMode.Open, FileAccess.Read)
Dim br As New BinaryReader(fStream)
Dim data As Byte() = br.ReadBytes(CInt(numBytes))
br.Close()
fStream.Close()
sql = "INSERT INTO " & attachmentTbl & " (DocID, DocName, DocType, DocFile, DocLength) " &
"VALUES ('" & dgv1.Rows(cnt1).Cells(0).Value & "', '" & dgv1.Rows(cnt1).Cells(1).Value & "', '" & dgv1.Rows(cnt1).Cells(2).Value & "', " data ", " & numBytes & ")"
sqlquery.CommandText = sql
'"VALUES (#DocID, #DocName, #DocType, #DocFile, #DocLength)"
'sqlquery.OleDbParameter.Add(New System.Data.SqlClient.SqlParameter("#DocID", dgv1.Rows(cnt1).Cells(0).Value))
'sqlquery.Parameters.Add(New System.Data.SqlClient.SqlParameter("#DocName", dgv1.Rows(cnt1).Cells(1).Value))
'sqlquery.Parameters.Add(New System.Data.SqlClient.SqlParameter("#DocType", dgv1.Rows(cnt1).Cells(2).Value))
'sqlquery.Parameters.Add(New System.Data.SqlClient.SqlParameter("#DocFile", data))
'sqlquery.Parameters.Add(New System.Data.SqlClient.SqlParameter("#DoDocLength", numBytes))
'sqlquery.ExecuteNonQuery()
Next
sqlconn.Close()
Catch ex As Exception
errorFlag = True
MessageBox.Show("Error#060 " & ex.Message)
Exit Sub
End Try
Also, Is there a way to get the file type displayed in windows explorer. I.e. for .pdf file the display with would "adobe acrobat document" .xls file would be "Microsoft excel worksheet"
I tried using the below code but I don't get the above stuff
extn = Path.GetExtension(txtFileName.Text)
Dim regKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(extn)
If Not regKey Is Nothing Then
Dim ct As Object = regKey.GetValue("Content Type")
If Not ct Is Nothing Then
extn = ct.ToString()
End If
End If
Appreicate your help.
i'm a newbye I have a problem with the vba code to import data from a table in excel file access. Using Office 2010, but the launch of the code gives me an error:
(translate from Italian)
run-time error -2147217865 (80040e37) Microsoft Access Database engine cannot find object 'INCONTRI$A1:I108468.
Make sure the object exists and that its name and the path you typed BE CORRECTED.
HERE IS THE CODE:
VB:
Sub EXPORT2ACCESS()
Dim ultimariga As Long
Dim ultimacolonna As Integer
Dim foglio, finesel As String
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\TOTALBET\TOTALBET_XML_DB.accdb"
dbWb = Application.ActiveWorkbook.FullName
For i = 1 To 4
ultimariga = Sheets(i).Range("A" & Rows.Count).End(xlUp).Row
ultimacolonna = Sheets(i).Cells(1, Sheets(i).Columns.Count).End(xlToLeft).Column
finesel = Application.ConvertFormula("R" & ultimariga & "C" & ultimacolonna, xlR1C1, xlA1, toAbsolute:=xlRelative)
foglio = Application.Sheets(i).Name
Set cn = CreateObject("ADODB.Connection")
Dim cmd As ADODB.Command
dsh = "[" & Application.Sheets(i).Name & "$A1:" & finesel & "]"
cn.Open strCon
Set cmd = New ADODB.Command
cmd.CommandType = adCmdText
cmd.CommandText = "Delete * from " & foglio
cmd.ActiveConnection = cn.ConnectionString
cmd.Execute
With Sheets(i)
For x = 1 To ultimacolonna
campo = "[" & .Cells(1, x).Value & "]"
If x = 1 Then
stringa = campo
Else
stringa = stringa & ", " & campo
End If
Next x
End With
''Insert into a table called
strsql = "INSERT INTO " & foglio & "(" & stringa & ") "
strsql = strsql & "SELECT * FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh
Debug.Print strsql
''Execute the statement
cn.Execute strsql
Next i
End Sub
the table "incontri" exists in my excel file and contain data. same sub worked for other sheets without problems and insert data in access table.
string that pass to exceute is:
VB:
INSERT INTO INCONTRI([Static_ID], [Stage_ID], [Season], [Number], [Data], [Time], [Status], [Venue_ID], [League]) SELECT * FROM [Excel 12.0;HDR=YES;DATABASE=C:\Users\Admin\Desktop\test xml.xlsm].[INCONTRI$A1:I108468]
Here is files (too big to put in forum, sorry:
Excel file with code and data: https://www.sugarsync.com/pf/D9350024_63096411_117675
Access file: https://www.sugarsync.com/pf/D9350024_63096411_117635
I'm going crazy to understand where the error is please help!
Thanks in advance to all the people who want to help me figure out where I'm wrong.
greetings
Vincent
You will probably find it easier to do this from Access. Access uses VBA like Excel, so you shouldn't have much trouble with it.
In Access, there's a command called DoCmd.TransferText. Click here for the full syntax.
Do a search for more examples. Good luck.
i find this code, when trying to create db, using adodb and adox.
Here you can check original, it is the same. Thanks for author
Private Sub Command1_Click()
Dim db_file As String
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim num_records As Integer
' Get the database name.
db_file = App.Path
If Right$(db_file, 1) <> "\" Then db_file = db_file & _
"\"
db_file = db_file & "People.mdb"
' Open a connection.
Set conn = New ADODB.Connection
conn.ConnectionString = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & db_file & ";" & _
"Persist Security Info=False"
conn.Open
' Drop the Employees table if it already exists.
On Error Resume Next
conn.Execute "DROP TABLE Employees"
On Error GoTo 0
' Create the Employees table.
conn.Execute _
"CREATE TABLE Employees(" & _
"EmployeeId INTEGER NOT NULL," & _
"LastName VARCHAR(40) NOT NULL," & _
"FirstName VARCHAR(40) NOT NULL)"
' Populate the table.
conn.Execute "INSERT INTO Employees VALUES (1, " & _
"'Anderson', 'Amy')"
conn.Execute "INSERT INTO Employees VALUES (1, 'Baker', " & _
" 'Betty')"
conn.Execute "INSERT INTO Employees VALUES (1, 'Cover', " & _
" 'Chauncey')"
' Add more records ...
' See how many records the table contains.
Set rs = conn.Execute("SELECT COUNT (*) FROM Employees")
num_records = rs.Fields(0)
conn.Close
MsgBox "Created " & num_records & " records", _
vbInformation, "Done"
End Sub
But how to make it more robust, so, i don't want to delete db.
How to check, if db exists and if db.tables contains my table?
additional question: am i right, that this code create db for ms-access 2007?
Thanks for help!
Your question includes these two:
How to check, if db exists and if db.tables contains my table?
am i right, that this code create db for ms-access 2007?
For the first part of #1, use the Dir() function.
If Len(Dir("C:\SomeFolder\YourDb.mdb")) > 0 Then
Debug.Print "db exists"
Else
Debug.Print "db not found"
End If
For the second part of #1, try this function. pTable is the name of the table you're checking for. pDbPath is the full path, including the file name, for the db file you want to examine. The path can be one which begins with a drive letter, or it can be a UNC path ( \\Server\Share\YourDb.mdb ).
Public Function TableExists(ByVal pTable As String, _
Optional ByVal pDbPath As String) As Boolean
'return True if pTable exists as either a native or linked table '
'pass any error to caller '
Dim blnReturn As Boolean
Dim db As DAO.Database
Dim tdf As DAO.TableDef
If Len(Trim(pDbPath)) > 0 Then
Set db = OpenDatabase(pDbPath)
Else
Set db = CurrentDb
End If
For Each tdf In db.TableDefs
If tdf.Name = pTable Then
blnReturn = True
Exit For
End If
Next tdf
Set tdf = Nothing
If Len(Trim(pDbPath)) > 0 Then
db.Close
End If
Set db = Nothing
TableExists = blnReturn
End Function
Regarding your second question, no that code you showed us does not create a db file for any Access version. If db_file is not the path to an existing db file, that code will throw an error at conn.Open. It does not create the missing db file.
However I doubt that code will compile as VBA, despite the fact you included VBA in your title and tagged your question as vba. Really you should have at least tried it first before including it in a question on Stack Overflow.
For creating a MDB file from VB6/VBA code you could use ADOX. Here's a sample function to create an MDB file.
Public Function CreateMDB(strDBPath As String) As Boolean
'To make code compile add a reference to Microsoft ADO Ext 2.x for DDL and Security
'(msADOX.dll)
Dim catDB As ADOX.Catalog
Dim tblNew As ADOX.Table
Dim keyPrim As New ADOX.Key
Set catDB = New ADOX.Catalog
If Dir(strDBPath) = "" Then
CreateMDB = False
End If
With catDB
.Create "Provider=Microsoft.Jet.OLEDB.4.0;Locale Identifier=" & _
1033 & ";Data Source=" & strDBPath
.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strDBPath
End With
Set tblNew = New ADOX.Table
With tblNew
.Name = "data"
With .Columns
.Append "Field_0", adVarWChar
.Append "Field_1", adVarWChar
.Append "Field_2", adVarWChar
.Append "Field_3", adVarWChar
End With
End With
catDB.Tables.Append tblNew
Set keyPrim = New ADOX.Key
With keyPrim
.Name = "Field_0"
.Type = adKeyPrimary
.RelatedTable = "data"
.Columns.Append "Field_0"
End With
catDB.Tables("data").Keys.Append keyPrim
Set catDB = Nothing
Set tblNew = Nothing
End Function
I have a desktop application using vb.net, to process some excel files, those files are stored in a sql server database.
Here is the code I have:
Try
conDCS.Open()
comDCS.Connection = conDCS
comDCS.CommandType = CommandType.Text
comDCS.CommandText = "select top 2 [Filename], [File] " & _
"from tblFiles (nolock) " & _
"where ([Filename] like 'DIG%' or [Filename] like 'FAC%') and " & _
"(UploadDate>='" & FromDate & "' and UploadDate<'" & ToDate & "')"
comDCS.ExecuteNonQuery()
rdrDCS = comDCS.ExecuteReader
If rdrDCS.HasRows Then
While rdrDCS.Read
Dim imageInBytes As Byte() = rdrDCS(1)
Dim memoryStream As System.IO.MemoryStream = New System.IO.MemoryStream(imageInBytes, False)
Dim image As System.Drawing.Image = System.Drawing.Image.FromStream(memoryStream)
image.Save(TempPath & rdrDCS(0))
End While
ToProcess = True
End If
rdrDCS.Close()
Catch ex As Exception
ToProcess = False
MessageBox.Show("Error accessing to the files: " & ex.Message)
Finally
conDCS.Close()
End Try
I'm getting: "Parameter is not valid" in this line:
Dim image As System.Drawing.Image = System.Drawing.Image.FromStream(memoryStream)
I have understood that this error is related to an invalid image data, but I can't figure it out what could be the problem.
imageInBytes has a length of 41473. And some items of the array have zero as value.
What could be wrong here, or perhaps, can anyone supply a working code to achieve this?
We use a common method to save a file from a database field to a file:
Public Function FieldToFile(ByVal sFileName As String, ByVal theField As Object) As Boolean
' Exceptions are handled by the caller
If theField IsNot DBNull.Value Then
Using oStream As New System.IO.FileStream(sFileName, IO.FileMode.Create, IO.FileAccess.Write)
If oStream IsNot Nothing Then
Dim aBytes As Byte()
aBytes = DirectCast(theField, Byte())
oStream.Write(aBytes, 0, aBytes.Length)
oStream.Close()
End If
End Using
End If
Return True
End Function
This can be called as follows:
Call FieldToFile(someFileName, rdrDCS(1)