"Automation Error" "Unspecified Error" When Using Excel-VBA and ADODB Objects - sql

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!

Related

"dbo_" Missing From DNS-Less Connected Tables

I've had a DNS-less connection to my SQL Servers for years... but all of a sudden some (not all) of the tables are coming across WITHOUT the "dbo_" in the table name. I need the "dbo_" in the table names. It doesn't affect all the tables, just some of them. What's interesting is that it's the same tables that get the "dbo_" and the same ones that do not get it.
All tablenames in the table start with "dbo_". Nothing has changed in the DB nor the server for years. It's a 2019 SQL Server.
Any ideas on why its doing this?
Private Sub cmdLogin_Click()
On Error GoTo Err_Login
Dim varUserName As String
Dim varPassword As String
Dim vardim As String
Dim varCreds As String
varUserName = Me.txtUserName
varPassword = Nz(Me.txtPassword, vbNullString)
varCreds = "UID=" & varUserName & ";PWD=" & varPassword
vardim = ";APP=2007 Microsoft Office system;DATABASE=xyz"
strConnection = "ODBC;Driver={ODBC Driver 17 for SQL Server};Server=xyz;" & varCreds & ";APP=2007 Microsoft Office system;DATABASE=xyz"
Dim dbCurrent As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set dbCurrent = DBEngine(0)(0)
Set qdf = dbCurrent.CreateQueryDef("")
Dim td As TableDef
'Columns in ActiveTablesToLink: (DatabaseName, LinkFlag, LocalTableName, ServerName, SSTableName)
strsql = "SELECT * FROM ActiveTablesToLink WHERE LinkFlag = -1 And DatabaseName = 'xyz'"
Set recLocal = CurrentDb.OpenRecordset(strsql)
recLocal.MoveLast
recLocal.MoveFirst
strRecCount = recLocal.RecordCount
If strRecCount > 0 Then
Do While Not recLocal.EOF
stLocalTableName = recLocal!LocalTableName
stRemoteTableName = recLocal!SSTableName
Set td = CurrentDb.CreateTableDef(stLocalTableName, dbAttachSavePWD, stRemoteTableName, strConnection)
CurrentDb.TableDefs.Append td
recLocal.MoveNext
Loop
Else
End If 'Empty recordset
recLocal.Close
Application.RefreshDatabaseWindow
DoCmd.Close acForm, "Login"
Exit_cmdLogin: ' Label to resume after error.
Exit Sub
Err_Login:
If DBEngine.Errors.Count > 1 Then
'ODBC Error
For Each errany In DBEngine.Errors
MsgBox "ODBCExecute: Err# " & errany.Number & " raised by " _
& errany.Source & ": " & errany.Description, _
vbCritical, "cmdExecuteAttached()"
Next errany
Else 'Access Error
MsgBox "ODBCExecute: Err# " & Err.Number & " raised by " _
& Err.Source & ": " & Err.Description, _
vbCritical, "cmdExecuteAttached()"
End If
Resume Exit_cmdLogin
End Sub
Here is where you put the code just in case you need to fix this via VBA:
Set td = CurrentDb.CreateTableDef(stLocalTableName, dbAttachSavePWD, stRemoteTableName, strConnection)
' Add this line before he append
td.Name = stLocalTableName
CurrentDb.TableDefs.Append td
recLocal.MoveNext
Thanks to Tim Williams to finding the bug article:
https://answers.microsoft.com/en-us/msoffice/forum/all/has-version-2212-of-ms-access-affected-attaching/e730184f-db94-4fa8-b144-491c638df87c

How to retrieve data from other Excel using VBA and SQL?

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.

Macro to Get Data from Iseries (AS400) using Excel VBA

I am getting data from AS400 via Excel add-in and I'm trying to find an automated to do this because I have to do this many times with various source files and it's annoying to constantly to having to log in whenever I use a new source file.
For instance, for the source file "bond.tto" I would do this to download it:
In Excel,
go to "Add-Ins" --> "Transfer Data from iSeries." A "Transfer Request" window pops up and from there I choose "create a new file"... the path and the file name is c:\bond.tto.
"starting cell position" I chose column A and row 1 and click "include column headings." I press "OK."
then I enter my credentials which let's say my user name is "abc" and pw is "abc." The server...let's call it "BLUE.TOR.MCFLY.COM."
Could somebody suggest code to automate this? Please and thank you.
The macro recorder doesn't give me any lines of code to work with.
No errors as the macro recorder doesn't work.
As a side note, you can also use open JT400 in java to use DB2 SQL to query your tables.
Using VBA you can also use queries as follows:
The code I am using here is primarily from VBA New Database Connection.
However, of importance to you is your database connection string.
This is using the Client Access ODBC driver to connect to an IBM i DB2 database on a server with the name POWER7 and other options. The "translate" option I believe takes it from the 65535 CSSID and converts it to something nice from EBDIC.
Sub DbConnection()
Dim cn As Object ' ADODB.Connection
Set cn = CreateObject("ADODB.Connection") ' New ADODB.Connection
Dim rs As Object ' ADODB.Recordset
Dim strConn As String
strConn = "DRIVER={Client Access ODBC Driver (32-bit)};" & _
"Database=<myDataBase>;" & _
"Hostname=<POWER7>;" & _
"Port=1234;" & _
"Protocol=TCPIP;" & _
"Uid=<USERID>;" & _
"Pwd=<PASSWORD>;" & _
"SYSTEM=<POWER7>;" & _
"DBQ=QGPL <YOUR BASE LIBRARY> <ANOTHER>;" & _
"DFTPKGLIB=QGPL;" & _
"LANGUAGEID=ENU;" & _
"PKG=QGPL/DEFAULT(IBM),2,0,1,0,512;QRYSTGLMT=-1;" & _
"TRANSLATE=1;" & _
"CONNTYPE=2;" & _
"REGIONAL=NO;"
cn.Open strConn
Dim queryArr, i
queryArr = Array("SELECT * FROM <LIBRARY>.<TABLE>")
For i = LBound(queryArr) To UBound(queryArr)
ExecuteQuery queryArr(i), cn, rs
Next i
cn.Close
Set cn = Nothing
End Sub
Private Sub ExecuteQuery(query As Variant, ByRef cn As Object, ByRef rs As Object)
Set rs = CreateObject("ADODB.Recordset") ' New ADODB.Recordset
With rs
.ActiveConnection = cn
.Open CStr(query)
Sheets("Sheet1").Range("A1").CopyFromRecordset rs
.Close
End With
Set rs = Nothing
End Sub
test this:
Option Explicit
Option Base 1
Sub Firmennamen()
On Error GoTo ERRORHANDLER
Dim sSQLFirmen As String
Dim objListObj As ListObject
Dim objListCols As ListColumns
Set WB = ThisWorkbook
Set ws_Einstellungen = WB.Worksheets("Einstellung") ' tab name in excel
Set objListObj = ws_Einstellungen.ListObjects("FirmenNamen") ' table name in excel
Set objListCols = objListObj.ListColumns
ws_Einstellungen.Range("FirmenNamen").ClearContents ' clear table
sconnect = "PROVIDER=IBMDA400;Data Source=server_name;USER ID=username;PASSWORD=Password;"
conn.ConnectionTimeout = 30
conn.Open sconnect
Set mrs.ActiveConnection = conn
sSQLFirmen = " SELECT t.col1 AS Nr, t.col2 AS Firma " & _
" From server_name.schema_name.table_name t " & _
" WHERE t.col2='010' " & _
" ORDER BY t.col1 "
mrs.Open sSQLFirmen, conn
For i = 0 To mrs.fields.count - 1
objListCols(i + 1).Name = mrs.fields(i).Name
Next i
ws_Einstellungen.Range("FirmenNamen").CopyFromRecordset mrs
mrs.Close
conn.Close
Set mrs = Nothing
Set conn = Nothing
Exit Sub
'get out before the Error Handler kicks in
'//////////////////////////////////////////////////////////
ERRORHANDLER:
Call ERROR
End
End Sub
Private Sub Workbook_Open()
Call Firmennamen ' when excel open --> query update
End Sub
Sub ERROR()
Select Case Err.Number
Case -2147217843
msg = "Sie müssen Ihre User ID und Password eintragen: " & Err.Number _
& " oder Ihre user ID und Password sind nicht correct."
MsgBox msg, vbOKOnly
Case 13
msg = "You have text data in a numeric field (" & BadField & "). Fix and re-Upload"
MsgBox msg, vbOKOnly
Case 1004
msg = "Firma fehlt oder ist ungültig !"
MsgBox msg, vbOKOnly
Case Else
msg = "DIe Fehler ist: " & Err.Number & " / " & Err.Description & vbCrLf & vbCrLf & " Bitte sich bei IT melden (mit Screenshot dieser Meldung) !! :( "
MsgBox msg, vbOKOnly
End Select
Err.Clear
'Set GetConnection = Nothing
End Sub

Can't union two tables even though ADODB confirms equal field counts

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.

Microsoft Access - Multiple Transactions when Inserting into Remote DB

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