How to import a CSV file when its name contains dots? - vba

I need to import .csv files via script from a read-only directory to an Access table.
It fails for files with dots in the name: e.g. fi.le.name.csv.
I found these solutions:
rename the file
copy the file and give it a name without dots
Is it possible to solve it differently?
Dim strSelect as String
Dim strFile as String
Dim strConnectionString as String
Dim strFolder as String
Dim rs as ADODB.Recordset
Dim cn as ADODB.Connection
Set rs = New ADODB.Recordset
Set cn = New ADODB.Connection
strFolder = "C:\path"
strConnectionString = "Provider=" & _
CurrentProject.Connection.Provider & _
";Data Source=" & strFolder & Chr(92) & _
";Extended Properties='text;HDR=YES;FMT=Delimited'"
cn.Open strConnectionString
strFile = "fi.le.name.csv"
strSelect = "SELECT * FROM " & strFile
rs.Open strSelect, cn, adOpenForwardonly 'and here is the failure

I tried use shortname, it's working for me:
Sub dots()
Dim strSelect As String
Dim strFile As String
Dim strConnectionString As String
Dim strFolder As String
Dim rs As ADODB.Recordset
Dim cn As ADODB.Connection
Set rs = New ADODB.Recordset
Set cn = New ADODB.Connection
strFolder = "c:\Users\Alex20\Documents" ' my path
strConnectionString = "Provider=" & _
"Microsoft.ACE.OLEDB.12.0" & _
";Data Source=" & strFolder & _
"\;Extended Properties='text;HDR=YES;FMT=Delimited'"
'Debug.Print strConnectionString
cn.Open strConnectionString
strFile = "fi.le.name.csv"
strFile = ShortName(strFile)
strSelect = "SELECT * FROM `" & strFile & "`"
Debug.Print strSelect 'SELECT * FROM `FILENA~1.CSV`
rs.Open strSelect, cn, adOpenForwardonly 'and here is the failure
Do While Not rs.EOF
Debug.Print rs.Fields(0), rs.Fields(1)
rs.MoveNext
Loop
End Sub
Function ShortName(filespec)
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(filespec)
ShortName = f.ShortName
End Function

Copy the file to another folder and rename it by deleting the dot. The connection syntax is also specified in another folder.
Sub test()
Dim strSelect As String
Dim strFile As String
Dim strConnectionString As String
Dim strFolder As String
Dim rs As ADODB.Recordset
Dim cn As ADODB.Connection
Dim strTarget As String
Set rs = New ADODB.Recordset
Set cn = New ADODB.Connection
strFolder = "C:\path"
strTarget = "C:\"
strConnectionString = "Provider=" & _
"Microsoft.ACE.OLEDB.12.0" & _
";Data Source=" & strTarget & Chr(92) & _
";Extended Properties='text;HDR=YES;FMT=Delimited'"
cn.Open strConnectionString
strFile = "fi.le.name.csv"
Dim vF As Variant, newFile As String
vF = Split(strFile, ".")
newFile = Replace(strFile, vF(UBound(vF)), "")
newFile = Replace(newFile, ".", "") & "." & vF(UBound(vF))
FileCopy strFolder & "\" & strFile, strTarget & newFile
strSelect = "SELECT * FROM " & newFile
rs.Open strSelect, cn 'and here is the failure
Debug.Print rs(0)
End Sub

Related

Missing data partially importing filtered text file data through sql with excel vba

I would like to import a 30Mb text file into excel filtering just what I want.
I have tried with small files and I see that some columns with byte data shows problems. I see a black sell or wrong values.
I tried different provider for the connection but I loose always data.
text_2.txt:
946737293;98FECB80;FF;FF;0;0;0;0;FF;FF
946737293;98EAFFFE;0;EE;0;0;0;0;FF;FF
946737294;98FE0F82;65;6E;4F;0;0;0;FF;FF
946737295;8CFD0282;FF;FF;FF;FF;FF;FF;0;FD
946737295;9CE78280;FF;1;5;FF;FF;FF;FF;FF
946737295;9CE78280;C0;FF;0;0;0;0;FF;FF
946737296;8CFD0282;FF;FF;FF;FF;FF;FF;0;FD
excel result
Sub FilterFile2()
Dim log_path As String
Dim log_file As String
Dim objConnection As ADODB.Connection 'Object
Dim objRecSet As ADODB.Recordset 'Object
Dim strConnection As String
Dim strSql As String
Dim strPath As String
Dim strTable As String
Dim ws As Variant
strPath = "I:\Codici\Excel\filtra_file_testo"
strTable = "test_2.txt"
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strPath & ";Extended Properties='Text;HDR=NO;IMEX=1'"
' SAME PROBLEM
'strConnection = "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
' "Dbq=" & strPath & ";Extensions=asc,csv,tab,txt;" 'HDR=NO;Persist Security Info=False"
'https://www.exceltip.com/import-and-export-in-vba/import-data-from-a-text-file-ado-using-vba-in-microsoft-excel.html
' SAME PROBLEM
'strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
'"Data Source=" & strPath & ";Extended Properties='Text;HDR=NO;IMEX=1'"
'ADOX doesn't read the data, you still use ADODB for that.
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open strConnection
strSql = "SELECT * " & _
" FROM " & strTable & _
" WHERE F3='FF'"
'" WHERE F2='9CE78280'" 'the same problem
Debug.Print strSql
Set objRecSet = New ADODB.Recordset
objRecSet.Open strSql, objConnection, adOpenForwardOnly, adLockReadOnly, adCmdText
'Set objRecSet = objConnection.Execute(strSql)
If objRecSet.State <> adStateOpen Then
objConnection.Close
Set objConnection = Nothing
Exit Sub
End If
'Copy Data to Excel'
Set ws = ActiveSheet
''ActiveCell.CopyFromRecordset objRecSet
ws.Cells(12, 2).CopyFromRecordset objRecSet 'write new data 'colonna 5 e 6 non corrette
objRecSet.Close
objConnection.Close
End Sub

Complications with moving data from SQL Server to Excel using VBA

I am trying to extract data from SQL Server into Excel to populate a pre-existing worksheet so I wrote a test code to this this out. While it is imperfect what I was mainly testing was establishing the connection to the server but I run into an Automation error Error 440 when I open the connection. What am I doing wrong within that portion of code.
I haven't made any modifications as of yet and have check to make sure it compiled just fine.
Sub GetPhysicalCount()
Dim squery As String
Dim cnLogs As New ADODB.Connection
Dim rsData As New ADODB.Recordset
Dim rsHeaders As New ADODB.Recordset
Dim x As Long
Dim y As Long
Dim dbpath As String
Dim dbname As String
Dim AppExcel As Excel.Application
Dim Workbook As Object
Dim Worksheet As Object
Dim strConn As String
Dim Count As Long
pUser = "AllenBroady"
pPsw = "Cthulu90"
pServer = "IMCPU_TEST"
pCatalog = "MasterMFG"
strConn = "Provider = SQLOLEDB;"
strConn = strConn & "Initial Catalog= & pCatalog; & Data Source= & pServer;"
strConn = strConn & "Integrated Security=sspi;& User ID= & pUser; & Password= & pPsw;"
cnLogs.Open strConn
With rsHeaders
.ActiveConnection = cnLogs
.Open "SELECT * FROM MasterMFG WHERE Dept_Code = 001"
Do While Not rsHeaders.EOF
Cells(1, l_counter + 1) = rsHeaders(0)
l_counter = l_counter + 1
rsHeaders.MoveNext
Loop
.Close
End With
With rsCount
.ActiveConnection = cnLogs
.Open "SELECT COUNT(Dept_Code)FROM MasterMFG WHERE Total <> 0"
Count = rsCount
.Close
End With
With rsData
.ActiveConnection = cnLogs
.Open "SELECT Dept_Code, Total FROM MasterMFG WHERE Total <> 0"
For i = 1 To Count
Sheet1.Range("A" & i + 1) = rsData.Fields(i)
rsData.MoveNext
Sheet1.Range("B" & i + 1) = rsData.Fields(i)
Next i
.Close
End With
cnLogs.Close
Set cnLogs = Nothing
Set rsHeaders = Nothing
Set rsData = Nothing
Sheets(1).UsedRange.EntireColumn.AutoFit
End Sub
I keep getting an "Automation" error (Error 440)
Your strConn = strConn strings are not concatenated properly.
Your variables aren't evaluating, their names are just being put straight into the string.
Change, e.g.
strConn = strConn & "Initial Catalog= & pCatalog; & Data Source= & pServer;"
strConn = strConn & "Integrated Security=sspi;& UserID= & pUser; & Password= & pPsw;"
to
strConn = strConn & "Initial Catalog=" & pCatalog & ";Data Source=" & pServer & ";"
strConn = strConn & "Integrated Security=sspi;User ID= "& pUser; & "Password= " & pPsw & ";"

VBA Excel SQL object variable or with block variable not set

Hi I keep getting an error when trying to upload to sql. The code have been working before, but I can find what I missed when rewriting the code..
it is falling at line:
cmd.CommandText = strSQL
the code is pretty simple it takes one column in a sheet and then upload or insert it in to an SQL database. please tell me what code I'm missing, or if I declare something wrong here
Dim cn As ADODB.Connection
Set sTroksheet = ThisWorkbook.Sheets("Mlist")
Set cn = New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strConn As String
Dim SQLstr As String
Dim SQLstrl As String
Dim Password As String
Dim Server_Name As String
Dim User_ID As String
Dim Database_Name As String
Dim Port_Name As String
Dim strTable As String
Dim excel_row As Long
Dim cmd As ADODB.Command
Dim rst_recordset As ADODB.Recordset
If ThisWorkbook.Sheets("Tournament Settings").Range("D4") = vbNullString
Then
MsgBox "Please setup database connection first in (DB Setup) in top menu"
Exit Sub
Else
Server_Name = Sheets("Software_Setup").Range("c3").Value
Database_Name = Sheets("Software_Setup").Range("c4").Value
User_ID = Sheets("Software_Setup").Range("c5").Value 'id user or username
Password = Sheets("Software_Setup").Range("c6").Value 'Password
Port_Name = Sheets("Software_Setup").Range("c7").Value 'Password
strConn = "Driver={MySQL ODBC 5.3 ANSI Driver};Server=" & _
Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
cn.Open strConn
LastRow = sTroksheet.Range("A65536").End(xlUp).row
strTable = Database_Name & ".TLHMember_List"
strSQL = "INSERT INTO " & strTable & _
" (Player) VALUES "
strSQL2 = ""
For excel_row = 1 To LastRow
strSQL2 = strSQL2 & _
"('" & sTroksheet.Cells(excel_row, 1) & "') ,"
Next excel_row
strSQL = strSQL & strSQL2
Mid(strSQL, Len(strSQL), 1) = ";" ' gets rid of the last comma
cmd.CommandText = strSQL
cmd.Execute
cn.Close
End If
You need to either change this line:
Dim cmd As ADODB.Command
to
Dim cmd As New ADODB.Command
or just before error line add new line:
Set cmd = new ADODB.Command
cmd.CommandText = strSQL

Could Not Find Installable ISAM Excel 2010

I have this sub in Excel 2010 that's supposed to copy in a table from Access 2010. When I try to run the code, it gives me a 'Could not find installable ISAM'. When I debug, it highlights objDB.Execute.
Private Sub btnGetData_Click()
Unload ParameterMenu
formWait.Show
'Save workbook
ActiveWorkbook.Save
Dim strExcelFile As String
Dim strWorksheet As String
Dim strDB As String
Dim strTable As String
Dim objDB As Database
strExcelFile = "X:\Form.xlsm"
strWorksheet = "RawDates"
strDB = "X:\Tables.accdb"
strTable = "Dates"
Set objDB = OpenDatabase(strDB)
objDB.Execute _ 'Error occurs here.
"SELECT * INTO [Excel 14.0;DATABASE=" & strExcelFile & _
"].[" & strWorksheet & "] FROM " & "[" & strTable & "]"
objDB.Close
Set objDB = Nothing
Unload formWait
FinishDialog.Show
End Sub
I'm not overly experienced with VBA, so any assistance would be greatly appreciated.
The correct format is 'Excel 12.0 Macro' rather than 'Excel 14.0':
objDB.Execute _ 'Error occurs here.
"SELECT * INTO [Excel 12.0 Macro;DATABASE=" & strExcelFile & _
"].[" & strWorksheet & "] FROM " & "[" & strTable & "]"
Edit:
Perhaps try ADO instead:
Private Sub btnGetData_Click()
Unload ParameterMenu
formWait.Show
'Save workbook
ActiveWorkbook.Save
Dim strExcelFile As String
Dim strWorksheet As String
Dim strDB As String
Dim strTable As String
Dim objDB As Object
Dim rs As Object
strExcelFile = "X:\Form.xlsm"
strWorksheet = "RawDates"
strDB = "X:\Tables.accdb"
strTable = "Dates"
Set objDB = CreateObject("ADODB.Connection")
With objDB
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & strDB & ";"
.Open
End With
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM " & "[" & strTable & "]", objDB, 3, 1, 1
If Not rs.EOF Then _
ThisWorkbook.Worksheets(strWorksheet).Cells(Rows.Count, "A").End(xlUp).Offset(1).CopyFromRecordset rs
rs.Close
objDB.Close
Set objDB = Nothing
Unload formWait
FinishDialog.Show
End Sub

Excel-Access ADO Update Values

I am trying to update a table in Access from the values in excel, however every time i run the code it creates new rows instead of updating the already existing ones, any ideas why? I am new to ADO, so any advised is well appreciated
Private Sub SelectMaster()
Dim db As New ADODB.Connection
Dim connectionstring As String
Dim rs1 As Recordset
Dim ws As Worksheet
Set ws = ActiveSheet
connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0; " & _
"Data Source=C:\Users\Giannis\Desktop\Test.mdb;"
db.Open connectionstring
Set rs1 = New ADODB.Recordset
rs1.Open "Men", db, adOpenKeyset, adLockOptimistic, adCmdTable
r = 6
Do While Len(Range("L" & r).Formula) > 0
With rs1
.AddNew
.Fields("Eva").Value = ws.Range("L" & r).Value
.Update
End With
r = r + 1
Loop
rs1.Close
'close database
db.Close
'Clean up
Set rs1 = Nothing
Set rs2 = Nothing
Set db = Nothing
End Sub
Here are some notes.
An example of updating row by row
''Either add a reference to:
''Microsoft ActiveX Data Objects x.x Library
''and use:
''Dim rs As New ADODB.Recordset
''Dim cn As New ADODB.Connection
''(this will also allow you to use intellisense)
''or use late binding, where you do not need
''to add a reference:
Dim rs As Object
Dim cn As Object
Dim sSQL As String
Dim scn As String
Dim c As Object
scn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\docs\dbto.mdb"
''If you have added a reference and used New
''as shown above, you do not need these
''two lines
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open scn
sSQL = "SELECT ID, SName, Results FROM [Test]"
''Different cursors support different
''operations, with late binding
''you must use the value, with a reference
''you can use built-in constants,
''in this case, adOpenDynamic, adLockOptimistic
''see: http://www.w3schools.com/ADO/met_rs_open.asp
rs.Open sSQL, cn, 2, 3
For Each c In Range("A1:A4")
If Not IsEmpty(c) And IsNumeric(c.Value) Then
''Check for numeric, a text value would
''cause an error with this syntax.
''For text, use: "ID='" & Replace(c.Value,"'","''") & "'"
rs.MoveFirst
rs.Find "ID=" & c.Value
If Not rs.EOF Then
''Found
rs!Results = c.Offset(0, 2).Value
rs.Update
End If
End If
Next
An easier option: update all rows
scn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\docs\dbto.mdb"
Set cn = CreateObject("ADODB.Connection")
cn.Open scn
sSQL = "UPDATE [Test] a " _
& "INNER JOIN " _
& "[Excel 8.0;HDR=YES;IMEX=2;DATABASE=C:\Docs\WB.xls].[Sheet1$] b " _
& "ON a.ID=b.ID " _
& "SET a.Results=b.Results"
cn.Execute sSQL, RecsAffected
Debug.Print RecsAffected
Your call to .AddNew is creating new rows.
Fionnuala
Many Thanks for the 'Easier Option' to update all rows.
Just to share that in my case (Office 2007 with Excel file in .xlsm format) I had to change the connection strings in order to reproduce the example:
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\docs\dbto.mdb"
...
& "[Excel 12.0 Xml;HDR=YES;IMEX=2;DATABASE=C:\Docs\WB.xls].[Sheet1$] b " _
EDIT: an example updating access row by row (using arrays)
On Error GoTo ExceptionHandling
With Application
'.EnableEvents = False
.ScreenUpdating = False
End With
Dim cnStr As String, sSQL As String, ArId As Variant, ArPrice As Variant, i As Integer, ws As Worksheet, LastRow as Long
Set ws = Sheets("Sheet1")
cnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ActiveWorkbook.Path & "\Test.mdb;Jet OLEDB:Database Password=123"
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.CursorLocation = adUseServer
cn.Open cnStr
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = cn
With ws
LastRow = .Cells(1000, 1).End(xlUp).Row
ArId = Application.Transpose(.Range(.Cells(17, 1), .Cells(LastRow, 1)))
ArPrice = Application.Transpose(.Range(.Cells(17, 3), .Cells(LastRow, 3)))
For i = 1 To UBound(ArId)
If ArPrice(i) = "" Then GoTo ContinueLoop
sSQL = "UPDATE PRICES SET Price = " & Replace(ArPrice(i), ",", ".") & " WHERE Id =" & ArId(i)
cmd.CommandText = sSQL
'For statements that don't return records, execute the command specifying that it should not return any records
'this reduces the internal work, so makes it faster
cmd.Execute , , adCmdText + adExecuteNoRecords
'another option using the connection object
'cn.Execute sSQL, RecsAffected
'Debug.Print RecsAffected
ContinueLoop:
Next i
End With
CleanUp:
On Error Resume Next
With Application
'.EnableEvents = True
.ScreenUpdating = True
End With
On Error Resume Next
Set cmd = Nothing
cn.Close
Set cn = Nothing
Exit Sub
ExceptionHandling:
MsgBox "Error: " & Err.Description & vbLf & Err.Number
Resume CleanUp
Below is an example of a reverse update query: updating a table in Excel from the values in Access.
(tested with Office 2007 and ADO 2.8, excel file in .xlsm format and access file in .mdb format)
Sub Update_Excel_from_Access()
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
'different options, tested OK
'cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ActiveWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=YES;"";"
'cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ActiveWorkbook.FullName & ";Extended Properties=Excel 12.0 Xml;"
cn.Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" & ActiveWorkbook.FullName & ";ReadOnly=0;"
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = cn
cmd.CommandText = "UPDATE [Sheet1$] a " _
& "INNER JOIN " _
& "[;Database=" & ThisWorkbook.Path & "\data.mdb].[Test] b " _
& "ON a.ID=b.ID " _
& "SET a.Results=b.Results"
cmd.Execute , , adCmdText
'Another option, tested OK
'sSQL = "UPDATE [Sheet1$] a " _
' & "INNER JOIN " _
' & "[;Database=" & ThisWorkbook.Path & "\data.mdb].[Test] b " _
' & "ON a.ID=b.ID " _
' & "SET a.Results=b.Results"
'cn.Execute sSQL, RecsAffected
'Debug.Print RecsAffected
Set cmd = Nothing
cn.Close
Set cn = Nothing
End Sub
Below is the same example but using a recordset object:
Sub Update_Excel_from_Access_with_Recordset()
Dim sSQL As String
On Error GoTo ExceptionHandling
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.CursorLocation = adUseServer
'different options, tested OK
'cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ActiveWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=YES;"";"
'cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ActiveWorkbook.FullName & ";Extended Properties=Excel 12.0 Xml;"
cn.Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" & ActiveWorkbook.FullName & ";ReadOnly=0;"
'Create a recordset object
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
sSQL = "SELECT a1.Results As er, a2.Results As ar " _
& "FROM [Sheet1$] a1 INNER JOIN [;Database=" & ThisWorkbook.Path & "\data.mdb].[Test] a2 " _
& " ON a1.[ID] = a2.[ID]"
With rst
.CursorLocation = adUseServer
.CursorType = adOpenKeyset
.LockType = adLockOptimistic
.Open sSQL, cn
If Not rst.EOF Then
Do Until rst.EOF
rst!er = rst!ar
.Update
.MoveNext
Loop
.Close
Else
.Close
End If
End With
CleanUp:
Cancelled = False
On Error Resume Next
cn.Close
Set rst = Nothing
Set cn = Nothing
Exit Sub
ExceptionHandling:
MsgBox "Error: " & Err.description
Resume CleanUp
End Sub