I have a problem with my code. I tried retrieving data from other Excel file. My code works but I received full data in one cell (A1). I'm sorry but I'm just beginner, believe that's the problem related to output, but I'm not find out why:
Sub RefreshData()
'Refresh data
Dim CreateNew As Object
Dim RunSELECT As Object
Dim Data As String
Dim SQL As String
FolderPath = ActiveWorkbook.path
path = Left(FolderPath, InStrRev(FolderPath, "\") - 1)
Set CreateNew = CreateObject("ADODB.Connection")
With CreateNew
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & path & "\Task1.xlsm; Extended Properties=Excel 12.0 Xml;HDR=YES;IMEX=1;CorruptLoad=xlRepairFile"
.Open
End With
'Run SQL
SQL = "SELECT * FROM [tw$]"
Set RunSELECT = CreateNew.Execute(SQL)
Do
output = output & RunSELECT(0) & ";" & RunSELECT(1) & ";" & RunSELECT(2) & vbNewLine
Debug.Print RunSELECT(0); ";" & RunSELECT(1) & ";" & RunSELECT(2)
RunSELECT.Movenext
Loop Until RunSELECT.EOF
ThisWorkbook.Worksheets("Dic").Range("A1").Value = output
RunSELECT.Close
CreateNew.Close
Set CreateNew = Nothing
Set RunSELECT = Nothing
End Sub
No need to wrap recordset values wtih semicolon delimiters using a Do loop. Simply use Range.CopyFromRecordset:
SQL = "SELECT * FROM [tw$]"
Set RunSELECT = CreateNew.Execute(SQL)
ThisWorkbook.Worksheets("Dic").Range("A1").CopyFromRecordset RunSELECT
RunSELECT.Close
CreateNew.Close
Set CreateNew = Nothing
Set RunSELECT = Nothing
ADOdb to Retrieve Data From Another Workbook (Without Opening It)
While playing around with Parfait's solution combined with a few posts, I came up with the function copySheetADOdb.
Adjust the constants under Source and Target in testCopySheetADOdb to test it.
The Code
Option Explicit
Sub testCopySheetADOdb()
' Initialize error handling.
Const ProcName = "testCopySheetADOdb"
On Error GoTo clearError ' Turn on error trapping.
' Source
Const Path As String = "F:\Test"
Const FileName As String = "Test.xlsx"
' Sheet Name ('SheetName') is case-insensitive i.e. 'A = a'.
Const SheetName As String = "Sheet1"
' Target
Const tgtName As String = "Sheet1"
Const tgtCell As String = "A1"
Dim wb As Workbook: Set wb = ThisWorkbook
' Define FilePath.
Dim FilePath As String
FilePath = Path & Application.PathSeparator & FileName
' Define Target Range.
Dim rng As Range
Set rng = wb.Worksheets(tgtName).Range(tgtCell)
' Test Result.
Dim Result As Boolean
Result = copySheetADODb(rng, FilePath, SheetName)
' Of course you can do all the above in one line:
'Result = copySheetADODB(Thisworkbook.Worksheets("Sheet1").Range("A1"), _
"C:\Test\Test.xlsx", "Sheet1")
' Inform user.
If Result Then
MsgBox "Worksheet successfully copied.", vbInformation, "Success"
Else
MsgBox "Worksheet not copied.", vbExclamation, "Failure"
End If
ProcExit:
Exit Sub
clearError:
Debug.Print "'" & ProcName & "':" & vbLf & " " & "Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
On Error GoTo 0 ' Turn off error trapping.
GoTo ProcExit
End Sub
Function copySheetADOdb(TargetCellRange As Range, _
ByVal SourceFilePath As String, _
Optional ByVal SourceSheetName As String = "Sheet1") _
As Boolean
' Initialize error handling.
Const ProcName = "copySheetADOdb"
On Error GoTo clearError ' Turn on error trapping.
' Test Target Cell Range ('TargetCellRange').
If TargetCellRange Is Nothing Then
GoTo NoTargetCellRange
End If
If TargetCellRange.Rows.Count > 1 Or TargetCellRange.Columns.Count > 1 Then
GoTo OneCellOnly
End If
'
' Define SQL Generic String.
Const sqlGeneric As String = "SELECT * FROM [SheetName$]"
Dim conn As Object
Set conn = CreateObject("ADODB.Connection")
Dim strErr As String
With conn
.Provider = "Microsoft.ACE.OLEDB.12.0"
' If you need the headers, HDR=NO means there are no headers
' (not: do not retrieve headers) so the complete data will be retrieved.
.ConnectionString = "Data Source='" _
& SourceFilePath _
& "';" _
& "Extended Properties='" _
& "Excel 12.0 Xml;" _
& "HDR=NO;" _
& "IMEX=1;" _
& "CorruptLoad=xlRepairFile" _
& "';"
On Error GoTo connOpenError
.Open
On Error GoTo clearError
' Run SQL.
Dim SQL As String
' Replace 'SheetName' in SQL Generic String
' with the actual sheet name ('SourceSheetName').
SQL = Replace(sqlGeneric, "SheetName", SourceSheetName)
Dim rs As Object
On Error GoTo connExecuteError
Set rs = .Execute(SQL)
On Error GoTo clearError
If Not TargetCellRange Is Nothing Then
' Copy sheet.
If Not rs.EOF Then
TargetCellRange.CopyFromRecordset rs
' Write result.
copySheetADOdb = True
Else
GoTo NoRecords
End If
End If
NoRecordsExit:
rs.Close
connExecuteExit:
.Close
End With
ProcExit:
Set rs = Nothing
connOpenExit:
Set conn = Nothing
Exit Function
NoTargetCellRange:
Debug.Print "'" & ProcName & "': " & "No Target Cell Range ('Nothing')."
GoTo ProcExit
OneCellOnly:
Debug.Print "'" & ProcName & "': " _
& "Target Cell Range has to be one cell range only."
GoTo ProcExit
NoRecords:
Debug.Print "'" & ProcName & "': No records found."
GoTo NoRecordsExit
connOpenError:
If Err.Number = "-2147467259" Then ' "-2147467259 (80004005)"
strErr = "'" & SourceFilePath & "' is not a valid path"
If Left(Err.Description, Len(strErr)) = strErr Then
Debug.Print "'" & ProcName & "': " & strErr & "..."
On Error GoTo 0 ' Turn off error trapping.
GoTo connOpenExit
End If
Else
GoTo clearError
End If
connExecuteError:
If Err.Number = "-2147467259" Then ' "-2147467259 (80004005)"
strErr = "'" & SourceSheetName & "' is not a valid name"
If Left(Err.Description, Len(strErr)) = strErr Then
Debug.Print "'" & ProcName & "': " & strErr & "..."
On Error GoTo 0 ' Turn off error trapping.
GoTo connExecuteExit
End If
Else
GoTo clearError
End If
clearError:
Debug.Print "'" & ProcName & "':" & vbLf & " " & "Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
On Error GoTo 0 ' Turn off error trapping.
GoTo ProcExit
End Function
You have problem in this code:
ThisWorkbook.Worksheets("Dic").Range("A1").Value = output
you are yourself asking to save the output to A1 Cell.
I would suggest you use for or while loop to enter the data in cells according to your need.
Related
I am creating a macro that looks through a folder, performs a SQL operation on each of the documents, and copies the results into another workbook; however, every time I debug and hit the Set rs = cn.Execute(sql) line I get an
"Automation Error" "Unspecified Error" .
The even weirder thing is that when I just run the code, I get an
"Execute of object _Connection failed" error.
I have tested the SQL code in microsoft SQL server already and each of these statements are almost verbatim with code I have previously got to work.
Option Explicit
Sub hardnessTests()
On Error GoTo ErrorHandling
Dim filename As Variant, n As Long
n = 0
Call turnOff
filename = Dir("T:\Marketing\Data Analytics\GIS Data\Water Quality Portal Data\County Summary Results\*")
While filename <> ""
Dim file As String, cn As Object, rs As Object, sql As String, hardField As ADODB.Field
file = "T:\Marketing\Data Analytics\GIS Data\Water Quality Portal Data\County Summary Results\" & filename
Set cn = CreateObject("ADODB.Connection")
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.connectionstring = "Data Source=" & file & ";Extended Properties=""Excel 12.0 Xml;HDR=YES;Readonly=false;IMEX=0"";"
.Open
End With
sql = "SELECT c.STATEFP, c.COUNTYFP, AVG(CAST(a.ResultMeasureValue AS NUMERIC)) AS Average_Surface_Water_Hardness, COUNT(a.ResultMeasureValue) AS Number_Of_Surface_Water_Tests, " & _
"AVG(CAST(b.ResultMeasureValue AS NUMERIC)) AS Average_Groundwater_Hardness, COUNT(b.ResultMeasureValue) AS Number_Of_Groundwater_Tests " & _
"FROM (SELECT * FROM [Sheet1$] WHERE CAST(LEFT(ActivityStartDate, 4) AS NUMERIC) >= 2010 and ActivityMediaSubdivisionName = 'Surface Water') a, " & _
"(SELECT * FROM [Sheet1$] WHERE CAST(LEFT(ActivityStartDate, 4) AS NUMERIC) >= 2010 AND ActivityMediaSubdivisionName = 'Groundwater') b, " & _
"(SELECT * FROM [Sheet1$] WHERE CAST(LEFT(ActivityStartDate, 4) AS NUMERIC) >= 2010 ) c GROUP BY c.STATEFP, c.COUNTYFP ORDER BY c.STATEFP, c.COUNTYFP"
Set rs = cn.Execute(sql)
Dim wb As Workbook, fieldCount As Long
fieldCount = 0
Set wb = Workbooks.Add
wb.SaveAs "T:\Marketing\Data Analytics\GIS Data\Water Quality Portal Data\County Summary Results\ALL_HARDNESS.xlsx"
If n = 0 Then
wb.Worksheets("Sheet1").Range("A2").CopyFromRecordset rs
Else:
wb.Worksheets("Sheet1").Range("A2").End(xlDown).CopyFromRecordset rs
End If
filename = Dir
n = n + 1
Wend
For Each hardField In rs.Fields
wb.Worksheets("Sheet1").Range("A1").Offset(0, fieldCount) = hardField.Name
fieldCount = fieldCount + 1
Next hardField
Call turnOn
Exit Sub
ErrorHandling:
MsgBox ("Source: " & Err.Source & vbNewLine & "Number: " & Err.Number & vbNewLine & "Description: " & Err.Description & vbNewLine & "Help Context: " & Err.HelpContext)
Done:
End Sub
Private Sub turnOff()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
End Sub
Private Sub turnOn()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = True
End Sub
Thanks for any help!
I'm not able to union two csvs even though ADODB confirms via .Fields.Count that they both have the same number of columns.
Here's the query that's failing:
select * from csv1.csv union select * from csv2.csv
with the error message:
The number of columns in the two selected tables or queries of a union query do not match
However, when I do select * from csv1.csv and select * from csv2.csv separately, ADODB confirms that .Fields.Count = 8 for both.
Possible key to the problem:
Do I need to create two separate connections? I'm only creating one connection (to the first csv) even though there are two csvs in the query.
I was trying to figure out how to do two separate connections for the same query and it seemed like people weren't finding that necessary - I couldn't find two connections mentioned in equivalent queries people were running against csvs.
Per #Parfait's request to see more of the code:
GetDataFromCSV
Public Function GetDataFromCSV(ByVal fileReport As Scripting.File, ByVal strQuery As String, ByVal arrSourceReports As Variant) As Boolean
Dim strRevisedQuery As String
strRevisedQuery = GetRevisedQueryWithFileAliasesReplacedWithTrueFileNames(strQuery, arrSourceReports)
Dim cnn As ADODB.Connection
Set cnn = OpenConnectionToCSV(fileReport)
If cnn Is Nothing Then
GetDataFromCSV = False
Exit Function
End If
GetDataFromCSV = QueryDataFromCSV(cnn, strRevisedQuery, fileReport.Name, fileReport.Name)
End Function
OpenConnectionToCSV
Private Function OpenConnectionToCSV(ByVal fileCSV As Scripting.File, Optional boolHeadersPresent As Boolean = True) As ADODB.Connection
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
cnn.ConnectionTimeout = 0
Dim strfileCSVParentFolderPath As String
strfileCSVParentFolderPath = fileCSV.ParentFolder
If Right(strfileCSVParentFolderPath, 1) <> Application.PathSeparator Then strfileCSVParentFolderPath = strfileCSVParentFolderPath & Application.PathSeparator
Dim strConn As String
If boolHeadersPresent = False Then
strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & strfileCSVParentFolderPath & ";Extended Properties=""text;HDR=NO;FMT=Delimited"""
Else
strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & strfileCSVParentFolderPath & ";Extended Properties=""text;HDR=YES;FMT=Delimited"""
End If
If strConn <> vbNullString Then
On Error GoTo ErrorHandler
Dim lngRetryCount As Long
lngRetryCount = 0
cnn.Open strConn
On Error GoTo 0
Set OpenConnectionToCSV = cnn
End If
Exit Function
ErrorHandler:
Select Case True
Case InStr(1, Err.Description, "Connect timeout occurred", vbTextCompare) > 0
If lngRetryCount < 30 Then
Application.Wait DateAdd("s", 1, Now)
lngRetryCount = lngRetryCount + 1
Resume
Else
MsgBox "Can't connect to " & fileCSV.Path & ". Reading this file will be skipped."
Exit Function
End If
Case Else
MsgBox "Getting data from " & fileCSV.Name & " has failed with the following error message: " & Err.Number & ": " & Err.Description
On Error GoTo 0
Resume
End Select
End Function
QueryDataFromCSV
Private Function QueryDataFromCSV(ByVal cnn As ADODB.Connection, ByVal strQuery As String, ByVal strCSVName As String, ByVal strFinalReportTitle As String) As Boolean
QueryDataFromCSV = True
Dim cmd As ADODB.Command
Set cmd = PrepareQueryCommand(cnn, strQuery)
CreateQueryDebugLog cmd.CommandText
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open cmd
Dim Loop1 As Long
With rst
For Loop1 = 1 To .Fields.Count
If .Fields(Loop1 - 1).Name = "F" & Loop1 Then
If Loop1 < 4 Then
MsgBox "Can't retrieve data from " & strCSVName & " because it is formatted improperly."
Else
MsgBox "Can't retrieve data from " & strCSVName & " because it is delimited improperly. The file is most likely delimited with a comma even though it has addresses or other fields that contain commas. Ask Encounters IT to change this report's delimiter to another character, such as | (pipe), in the Tidal batch file."
End If
QueryDataFromCSV = False
Exit Function
End If
Next Loop1
End With
CopyThisCSVRecordsetToResultSheets rst, strFinalReportTitle
cnn.Close
Set rst = Nothing
Set cmd = Nothing
Set cnn = Nothing
End Function
The error is occurring at rst.Open cmd in the above function QueryDataFromCSV
Illustrating schema.ini creation for #Comintern:
GetRevisedQueryWithFileAliasesReplacedWithTrueFileNames
Private Function GetRevisedQueryWithFileAliasesReplacedWithTrueFileNames(ByVal strQuery As String, ByVal arrSourceReports As Variant) As String
Dim FSO As Scripting.FileSystemObject
Set FSO = New Scripting.FileSystemObject
Dim lngPosition As Long
lngPosition = 0
Do Until lngPosition > Len(strQuery)
Dim lngStartPosition As Long
lngStartPosition = InStr(lngPosition + 1, strQuery, "from", vbTextCompare) + 5
If lngStartPosition > lngPosition Then
Dim lngEndPosition As Long
lngEndPosition = InStr(lngStartPosition + 1, strQuery, " ", vbTextCompare)
If lngEndPosition = 0 Then lngEndPosition = Len(strQuery) + 1
Dim strSourceReportTitle As String
strSourceReportTitle = Mid(strQuery, lngStartPosition, lngEndPosition - lngStartPosition)
Dim Loop2 As Long
For Loop2 = LBound(arrSourceReports, 1) To UBound(arrSourceReports, 1)
If arrSourceReports(Loop2, 1) = strSourceReportTitle Then Exit For
Next Loop2
Dim fileSource As Scripting.File
Set fileSource = FSO.GetFile(arrSourceReports(Loop2, 3))
If arrSourceReports(Loop2, 2) = "TAB" Then arrSourceReports(Loop2, 2) = Chr(9)
CreateSchemaIni fileSource, arrSourceReports(Loop2, 2)
Dim strRevisedQuery As String
If strRevisedQuery = vbNullString Then
strRevisedQuery = Replace(strQuery, "from " & strSourceReportTitle, "from " & fileSource.Name)
Else
strRevisedQuery = Replace(strRevisedQuery, "from " & strSourceReportTitle, "from " & fileSource.Name)
End If
lngPosition = lngEndPosition
Else
lngPosition = Len(strQuery) + 1
End If
Loop
GetRevisedQueryWithFileAliasesReplacedWithTrueFileNames = strRevisedQuery
End Function
CreateSchemaIni
Private Sub CreateSchemaIni(ByVal fileReport As Scripting.File, ByVal strDelimiter As String)
Dim intSystemFileNumber As Integer
intSystemFileNumber = FreeFile()
On Error GoTo ErrorHandler
Open fileReport.ParentFolder.Path & Application.PathSeparator & "Schema.ini" For Output As #intSystemFileNumber
Print #intSystemFileNumber, "[" & fileReport.Name & "]"
Print #intSystemFileNumber, "Format=Delimited(" & strDelimiter & ")"
Close #intSystemFileNumber
Exit Sub
ErrorHandler:
Select Case True
Case InStr(1, Err.Description, "Path/File Access Error", vbTextCompare) > 0
Dim strStandardQueryDebugLogPath As String
strStandardQueryDebugLogPath = fileReport.ParentFolder.Path & Application.PathSeparator & "strQuery.txt"
MsgBox strStandardQueryDebugLogPath & " was inaccessible. Creating log in same folder where your copy of the Mass Queryer is saved instead."
Open Left(ThisWorkbook.Path, InStrRev(ThisWorkbook.Path, Application.PathSeparator, , vbTextCompare)) & "strQuery.txt" For Output As #intSystemFileNumber
Print #intSystemFileNumber, "[" & fileReport.Name & "]"
Print #intSystemFileNumber, "Format=Delimited(" & strDelimiter & ")"
Close #intSystemFileNumber
Exit Sub
Case Else
MsgBox "Creating a query debug log has failed with the following error message: " & Err.Number & ": " & Err.Description
On Error GoTo 0
Resume
End Select
End Sub
With #Comintern's help, I was able to see that I made a silly mistake having nothing to do with the question title in actuality. You can see above that my CreateSchemaIni method was creating and then overwriting the Schema.ini file for each csv I was querying rather than creating and then appending to it. By changing that method to use Open For Append instead of Open For Output, the problem was solved.
I am working on a VBA macro which connects to my database on SQL Server and run some queries and save the results on CSV files... it works fine just when the queries returns data but i have days where the query doesn't return any results, just an empty table. I made a temporary solution based on checking the date and according it the macro runs that query or no... I want to make it other way now in my code so that i don't need to change the date everytime manually...
I tried these solutions :
If (objMyRecordset.EOF = False) Or (objMyRecordset.BOF = False) Then
Also this
If objMyRecordset.RecordCount <> 0 Then
but the problem is my Recordset is empty because the query doesn't return any rows so it shows me error in objMyRecordset.Open
I want to add a line of code like this for example :
'// Pseudo Code
If (the query doesn't return result) Then
( just the headers will be save on my file )
Else
(do the rest of my code)
End If
Here is my code. Any suggestions please ? Thank you very much.
Sub Load_after_cutoff_queryCSV()
Dim objMyConn As ADODB.Connection
Dim objMyCmd As ADODB.Command
Dim objMyRecordset As ADODB.Recordset
Dim fields As String
Dim i As Integer
Set objMyConn = New ADODB.Connection
Set objMyCmd = New ADODB.Command
Set objMyRecordset = New ADODB.Recordset
'Open Connection
objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=*****;User ID=*****;Password=*****;"
objMyConn.Open
'Set and Excecute SQL Command
Set objMyCmd.ActiveConnection = objMyConn
objMyCmd.CommandText = "SELECT * FROM [vw_X86_LOAD_AFTER_CUTOFF_REPORT_GAMMA]"
objMyCmd.CommandType = adCmdText
'Open Recordset
Set objMyRecordset.Source = objMyCmd
objMyRecordset.Open
Workbooks.Open Filename:="C:\Reports\load_after_cutoff_postGamma.csv"
Workbooks("load_after_cutoff_postGamma.csv").Sheets("load_after_cutoff_postGamma").Activate
ActiveSheet.Range("A2").CopyFromRecordset objMyRecordset
For i = 0 To objMyRecordset.fields.Count - 1
Worksheets("load_after_cutoff_postGamma").Cells(1, i + 1) = objMyRecordset.fields(i).name
Next i
Workbooks("load_after_cutoff_postGamma.csv").Sheets("load_after_cutoff_postGamma").Cells.EntireColumn.AutoFit
Workbooks("load_after_cutoff_postGamma.csv").Close SaveChanges:=True
MsgBox "Your file has been saved as load_after_cutoff_postGamma.csv"
If you experience problems connecting to your server then this is due to any of the following:
an incorrect connection string
incorrect credentials
the server is not reachable (for example: network cable disconnected)
the server is not up and running
Sending a query to a server which results in an empty recordset is not a reason for an ADODB.Connection to fail.
Here is a little bit of code for you to try and debug the connection in a first step and then the query in a second step:
Option Explicit
Public Sub tmpSO()
Dim strSQL As String
Dim strServer As String
Dim strDatabase As String
Dim OutMail As Outlook.MailItem
Dim rstResult As ADODB.Recordset
Dim conServer As ADODB.Connection
Dim OutApp As Outlook.Application
strServer = "."
strDatabase = "master"
Set conServer = New ADODB.Connection
conServer.ConnectionString = "PROVIDER=SQLOLEDB; " _
& "DATA SOURCE=" & strServer & ";" _
& "INITIAL CATALOG=" & strDatabase & ";" _
& "User ID='UserNameWrappedInSingleQuotes'; " _
& "Password='PasswordWrappedInSingleQuotes'; "
On Error GoTo SQL_ConnectionError
conServer.Open
On Error GoTo 0
strSQL = "set nocount on; "
strSQL = strSQL & "select * "
strSQL = strSQL & "from sys.tables as t "
strSQL = strSQL & "where t.name = ''; "
Set rstResult = New ADODB.Recordset
rstResult.ActiveConnection = conServer
On Error GoTo SQL_StatementError
rstResult.Open strSQL
On Error GoTo 0
If Not rstResult.EOF And Not rstResult.BOF Then
ThisWorkbook.Worksheets(1).Range("A1").CopyFromRecordset rstResult
' While Not rstResult.EOF And Not rstResult.BOF
' 'do something
' rstResult.MoveNext
' Wend
Else
'https://msdn.microsoft.com/en-us/library/windows/desktop/ms675546(v=vs.85).aspx
Select Case conServer.State
'adStateClosed
Case 0
MsgBox "The connection to the server is closed."
'adStateOpen
Case 1
MsgBox "The connection is open but the query did not return any data."
'adStateConnecting
Case 2
MsgBox "Connecting..."
'adStateExecuting
Case 4
MsgBox "Executing..."
'adStateFetching
Case 8
MsgBox "Fetching..."
Case Else
MsgBox conServer.State
End Select
End If
Set rstResult = Nothing
Exit Sub
SQL_ConnectionError:
MsgBox "Couldn't connect to the server. Please make sure that you have a working connection to the server."
Set OutApp = New Outlook.Application
Set OutMail = OutApp.CreateItem(0)
With OutMail
.Subject = "Problems connecting to database '" & strDatabase & "' hosted on the server '" & strServer & "'"
.HTMLBody = "<span style=""font-size:10px"">---Automatically generated Error-Email---" & _
"</span><br><br>Error report from the file '" & _
"<span style=""color:blue"">" & ThisWorkbook.Name & _
"</span>' located and saved on '<span style=""color:blue"">" & _
ThisWorkbook.Path & "</span>'.<br>" & _
"Excel is not able to establish a connection to the server. Technical data to follow." & "<br><br>" & _
"Computer Name: <span style=""color:green;"">" & Environ("COMPUTERNAME") & "</span><br>" & _
"Logged in as: <span style=""color:green;"">" & Environ("USERDOMAIN") & "/" & Environ("USERNAME") & "</span><br>" & _
"Domain Server: <span style=""color:green;"">" & Environ("LOGONSERVER") & "</span><br>" & _
"User DNS Domain: <span style=""color:green;"">" & Environ("USERDNSDOMAIN") & "</span><br>" & _
"Operating System: <span style=""color:green;"">" & Environ("OS") & "</span><br>" & _
"Excel Version: <span style=""color:green;"">" & Application.Version & "</span><br>" & _
"<br><span style=""font-size:10px""><br>" & _
"<br><br>---Automatically generated Error-Email---"
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
Exit Sub
SQL_StatementError:
MsgBox "There seems to be a problem with the SQL Syntax in the programming."
Set OutApp = New Outlook.Application
Set OutMail = OutApp.CreateItem(0)
With OutMail
.Subject = "Problems with the SQL Syntax in file '" & ThisWorkbook.Name & "'."
.HTMLBody = "<span style=""font-size:10px"">" & _
"---Automatically generated Error-Email---" & _
"</span><br><br>" & _
"Error report from the file '" & _
"<span style=""color:blue"">" & _
ActiveWorkbook.Name & _
"</span>" & _
"' located and saved on '" & _
"<span style=""color:blue"">" & _
ActiveWorkbook.Path & _
"</span>" & _
"'.<br>" & _
"It seems that there is a problem with the SQL-Code within trying to upload an extract to the server." & _
"SQL-Code causing the problems:" & _
"<br><br><span style=""color:green;"">" & _
strSQL & _
"</span><br><br><span style=""font-size:10px"">" & _
"---Automatically generated Error-Email---"
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
Exit Sub
End Sub
Note, that the above code clearly distinguishes between (first) connecting to the server and then (afterwards) issuing a query to the server to retrieve some data. Both steps are separated and there is a different error handler for either case.
Furthermore, the above sample code also results in an empty recordset being returned. But the code is able to handle that incident with yet another error handler.
If the connection fails or if the SQL syntax being sent to the server contains error(s) then the above code will automatically generate an error email (using Outlook) with some details for you to check the connection and the SQL syntax.
you should go with your .EOF solution. Here is an example of mine, which I use regularly.
Sub AnySub()
''recordsets
Dim rec as ADODB.Recordset
''build your query here
sSql = "SELECT * FROM mytable where 1=0" ''just to have no results
''Fire query
Set rec = GetRecordset(sSql, mycnxnstring)
''and then loop throug your results, if there are any
While rec.EOF = False
''do something with rec()
rec.MoveNext
Wend
End sub
Here the Function GetRecordset() is given by:
Function GetRecordset(strQuery As String, connstring As String) As Recordset
Dim DB As ADODB.Connection
Dim rs As ADODB.Recordset
Set DB = New ADODB.Connection
With DB
.CommandTimeout = 300
.ConnectionString = connstring
.Open
End With
Set GetRecordset = DB.Execute(strQuery)
End Function
Hope this helps.
I'm currently trying to do multiple inserts from an access database to a remote sql server. Thus far I've had no luck. When I attempt to code in a workspace and transactions I receive a data mismatch error, but the functional insert works perfectly fine separately.
Here is my code: Transaction One has been commented out
Private Sub cmdInsSqlSrvr_Click()
On Error GoTo ErrHandler
Dim dbAccess As DAO.Database
Dim strTableName As String
Dim strSQL As String
Dim strSqlServerDB As String
Dim strTableName2 As String
Dim cInTrans As Boolean
Dim wsp As DAO.Workspace
strTableName = "po_header_sql"
strTableName2 = "po_line_Sql"
'<configuration specific to SQL Server ODBC driver>
strSqlServerDB = "ODBC;DRIVER={SQL Server};" & _
"Server=;" & _
"DATABASE=;" & _
"Uid=;" & _
"Pwd=;"
'Start Transaction One
'Set dbAccess = DBEngine(0)(0)
' strSQL = "INSERT INTO [" & strSqlServerDB & "].TABLE3 SELECT * FROM " & strTableName & ";"
'dbAccess.Execute strSQL, dbFailOnError
'InitConnect = True
'MsgBox (dbAccess.RecordsAffected & " records have been moved from " & strTableName & " to remote DB")
'Command9.SetFocus
'cmdInsSqlSrvr.Enabled = False
'cmdInsertTbl.Enabled = True
' End Transaction One
'Begin Transaction Two
Set wsp = DBEngine(0)(0)
wsp.BeginTrans
Set dbAccess = wsp(0)
cInTrans = True
strSQL = "INSERT INTO [" & strSqlServerDB & "].TABLE4 SELECT * FROM " & strTableName2 & ";"
dbAccess.Execute strSQL, dbFailOnError
InitConnect = True
MsgBox (dbAccess.RecordsAffected & " records have been moved from " & strTableName & " to remote DB")
wsp.CommitTrans
cInTrans = False
Command9.SetFocus
cmdInsSqlSrvr.Enabled = False
cmdInsertTbl.Enabled = True
'End Transaction Two
ExitProcedure:
On Error Resume Next
Set dbAccess = Nothing
Exit Sub
ErrHandler:
InitConnect = False
MsgBox Err.Description, vbExclamation, "Moving data to Sql Server failed: Error " & Err.Number
Resume ExitProcedure
End Sub
Fixed it by separating the insert statements and putting dbAccess.Execute after each one. Also cleaned up the code substantially. Code follows:
Private Sub cmdInsSqlSrvr_Click()
On Error GoTo ErrHandler
Dim dbAccess As DAO.Database
Dim strTableName As String
Dim strSQL As String
Dim strSqlServerDB As String
Dim strTableName2 As String
strTableName = "po_header_sql"
strTableName2 = "po_line_Sql"
'<configuration specific to SQL Server ODBC driver>
strSqlServerDB = "ODBC;DRIVER={SQL Server};" & _
"Server=<server ip>;" & _
"DATABASE=<database name>;" & _
"Uid=<database uid>;" & _
"Pwd=<database password>;"
Set dbAccess = DBEngine(0)(0)
strSQL = "INSERT INTO [" & strSqlServerDB & "].TABLE3 SELECT * FROM " & strTableName & ";"
dbAccess.Execute strSQL, dbFailOnError
MsgBox (dbAccess.RecordsAffected & " records have been moved from " & strTableName & " to remote DB")
strSQL = "INSERT INTO [" & strSqlServerDB & "].TABLE4 SELECT * FROM " & strTableName2 & ";"
dbAccess.Execute strSQL, dbFailOnError
InitConnect = True
MsgBox (dbAccess.RecordsAffected & " records have been moved from " & strTableName2 & " to remote DB")
Command9.SetFocus
cmdInsSqlSrvr.Enabled = False
cmdInsertTbl.Enabled = True
ExitProcedure:
On Error Resume Next
Set dbAccess = Nothing
Exit Sub
ErrHandler:
InitConnect = False
MsgBox Err.Description, vbExclamation, "Moving data to Sql Server failed: Error " & Err.Number
Resume ExitProcedure
End Sub
I have a file like this:
strPath = "S:\HR\Forms\forms_database.accdb"
I am connecting to it through an WORD adodb.connection
should my database be a different extension ? MDB or something?
I am getting this error when it tries to connect:
unrecognized database format 's:...............accdb'
what's going on here?
here's the entire code:
Sub TransferShipper()
'Transfer new shipping company record to
'Shippers table in Northwind database.
Dim cnn As ADODB.Connection
Dim strConnection As String
Dim strSQL As String
Dim strPath As String
Dim doc As Word.Document
Dim strCompanyName As String
Dim strPhone As String
Dim bytContinue As Byte
Dim lngSuccess As Long
Set doc = ThisDocument
On Error GoTo ErrHandler
strCompanyName = Chr(39) & doc.FormFields("txtCompanyName").Result & Chr(39)
strPhone = Chr(39) & doc.FormFields("txtPhone").Result & Chr(39)
'Confirm new record.
bytContinue = MsgBox("Do you want to insert this record?", vbYesNo, "Add Record")
Debug.Print bytContinue
'Process input values.
If bytContinue = vbYes Then
strSQL = "INSERT INTO vacation " _
& "(title, department) " _
& "VALUES (" _
& strCompanyName & ", " _
& strPhone & ")"
Debug.Print strSQL
'Substitute path and connection string with DSN if available.
strPath = "S:\HR\Forms\forms_database.accdb"
strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source = " & strPath
Debug.Print strConnection
Set cnn = New ADODB.Connection
cnn.Open strConnection
cnn.Execute strSQL, lngSuccess
cnn.Close
MsgBox "You inserted " & lngSuccess & " record", _
vbOKOnly, "Error Added"
doc.FormFields("txtCompanyName").TextInput.Clear
doc.FormFields("txtPhone").TextInput.Clear
End If
Set doc = Nothing
Set cnn = Nothing
Exit Sub
ErrHandler:
MsgBox Err.Number & ": " & Err.Description, _
vbOKOnly, "Error"
On Error GoTo 0
On Error Resume Next
cnn.Close
Set doc = Nothing
Set cnn = Nothing
End Sub
Try ACE OLEDB 12.0 as the db version.
"Provider=Microsoft.ACE.OLEDB.12.0"