As the title suggests, I wondered if it was possible to populate a RecordSource or RowSource without maintaining a persistent connection to the external database I am querying.
I have tried two methods listed below to no avail:
IN Clause
ps.RecordSource = " SELECT TM_Adjudicator AS Adjudicator, Nz(Sum(PS_DB_view.PS_Points+PS_DB_view.PS_Adhoc),0) AS [Total Points] " & _
" FROM SD_Adjudicators_view " & _
" LEFT JOIN PS_DB_view ON (((cstr(SD_Adjudicators_view.TM_Adjudicator) = cstr(PS_DB_view.PS_Adjudicator)) AND cdate(PS_DB_view.PS_Date) >= #" & dtStart_fmt & "#) AND cdate(PS_DB_view.PS_Date) <= #" & dtEnd_fmt & "#) " & _
" IN '' [MS Access;PWD=**STRING**;DATABASE=I:\**PATH**\PM_DB_view.accdb] " & _
" WHERE SD_Adjudicators_view.TM_TeamName = 'Z999' " & _
" GROUP BY TM_Adjudicator; "
(this maintains a persistent connection for the life of the userform
DB.Connection
Set dbs = OpenDatabase("I:\**PATH**\PM_DB_testenvironment.accdb", False, False, "MS Access;**STRING**")
Set rst = dbs.OpenRecordset(" SELECT TM_Adjudicator AS Adjudicator, Nz(Sum(PS_DB_view.PS_Points+PS_DB_view.PS_Adhoc),0) AS [Total Points] " & _
" FROM SD_Adjudicators_view " & _
" LEFT JOIN PS_DB_view ON (((cstr(SD_Adjudicators_view.TM_Adjudicator) = cstr(PS_DB_view.PS_Adjudicator)) AND cdate(PS_DB_view.PS_Date) >= #" & dtStart_fmt & "#) AND cdate(PS_DB_view.PS_Date) <= #" & dtEnd_fmt & "#) " & _
" WHERE SD_Adjudicators_view.TM_TeamName = 'Z999' " & _
" GROUP BY TM_Adjudicator; ")
Set ps.Form.RecordSource = rst
rst.Close
Set rst = Nothing
dbs.Close
Set dbs = Nothing
This too maintains a persistent connection until the close function is called, and the RowSource / RecordSource values are lost.
Is there anyway to read the data, display it, and close the database whilst keeping the records visible?
Yes, there is.
You can use an ADODB disconnected recordset as your record source.
Code:
Dim conn As Object
Set conn = CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=I:\**PATH**\PM_DB_testenvironment.accdb;Jet OLEDB:Database Password=""**STRING**"""
Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.CursorLocation = 3 'adUseClient
rs.Open "SELECT stuff FROM Table", conn, 3, 3 'adOpenStatic, adLockReadOnly
Set Me.Recordset = rs
conn.Close
Set rs.ActiveConnection = Nothing
Set conn = Nothing
Note that many features, like sorting and filtering, won't work unless you first re-establish the database connection.
DAO unfortunately doesn't offer this functionality.
Related
I am using SQL update query in VBA and I am getting the datatype mismatch error. I know that error is basically because of the column spare part. The spare part column contains numeric and alphanumeric values.
Public Function UpdateDistinctColumnFRNumberBasis()
StrInvoiceNumber = "109839-01"
FRSparepartNumber = "FT7119907459"
MergedInvoiceFile = "/test.xlsx"
Dim objConn As Object
Dim objRecordSet As Object
Set objConn = CreateObject("ADODB.Connection")
Set objRecCmd = CreateObject("ADODB.Command")
Set objRecCmd_Update = CreateObject("ADODB.Command")
objConn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
MergedInvoiceFile & ";Extended Properties=""Excel 8.0;""")
strSQL = " Update [Tabelle1$] SET [Status] = 'Include' Where " & _
"([RECHNR] ='" & StrInvoiceNumber & "' AND [Sparepart] = " & FRSparepartNumber & ")"
objConn.Execute strSQL
objConn.Close
End Function
As commented, the partnumber is text, thus it must be quoted in the SQL:
FRSparepartNumber = "FT7119907459"
' snip
strSQL = "Update [Tabelle1$] SET [Status] = 'Include' Where " & _
"([RECHNR] = '" & StrInvoiceNumber & "' AND " & _
"[Sparepart] = '" & FRSparepartNumber & "')"
I have an excel spreadsheet that I'm trying to perform SQL queries on. I get "no value given for one or more required parameters", so I think it's a problem with my query. I can do a query like "SELECT * FROM [Employee$A2:A4]", but when I reference a particular column using the name (i.e. name, title...etc, or even using the generic column reference like F1) I get "No value given for one or more required parameters."
Here's my code:
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
strFile = ThisWorkbook.FullName
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile _
& ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
strSQL = "SELECT Employee FROM [Employee$] AS e WHERE e.Skill_Title = " & """" & skillTitle & """" & " AND e.Branch = " & """" & branchTitle & """" & " AND e.Skill_Prof = 5"
rs.Open strSQL, cn
MsgBox (rs.GetString)
Any ideas what might be going on?
Try applying the following example.
Tell me if the problem persists and the inputs you're using.
I have this on Employee sheet:
Created "MyQuery" subprocess as follows (as you can see, this is a replica of your code, with some little differences):
Sub MyQuery(ByVal skillTitle As String, _
ByVal branchTitle As String, _
ByVal skillProf As Integer)
Dim Cn As ADODB.Connection
Dim Rs As ADODB.Recordset
strFile = ThisWorkbook.FullName
strCon = _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strFile & ";" & _
"Extended Properties=""Excel 12.0;" & _
"HDR=Yes;" & _
"IMEX=1"";"
Set Cn = CreateObject("ADODB.Connection")
Set Rs = CreateObject("ADODB.Recordset")
Cn.Open strCon
strSQL = _
"SELECT Employee " & _
"FROM [Employee$] AS e " & _
"WHERE e.Skill_Title = '" & skillTitle & "' AND " & _
"e.Branch = '" & branchTitle & "' AND " & _
"e.Skill_Prof = " & CStr(skillProf)
Rs.Open strSQL, Cn
MsgBox (Rs.GetString)
'Do not forget closing your connection'
Rs.Close
Cn.Close
End Sub
Made a quick test:
Sub test()
'Try running this'
Call MyQuery("FOUR", "Y", 5)
End Sub
Result:
Have you named the columns? I wasn't sure from your code example whether you had named the columns or were assuming the column header would suffice for a reference. A "named" column is not the same as using a column header. To access the column by name try assigning a name to the column first.
From: How to give a name to the columns in Excel
Click the letter of the column you want to change and then click the "Formulas" tab.
Click "Define Name" in the Defined Names group in the Ribbon to open the New Name window.
Enter the new name of the column in the Name text box.
I'm working on an excel file to collect information from others closed Excel files
The provider is Microsoft.ACE.OLEDB.12.0 and everything works fine (almost).
In order to have updateable query, I used the command HDR = no in order to have column name like F1, F2, F3... and I retrieve the name after (see the code below, code from Stack Overflow).
However, with the command Union All, I also retrieved the headers as data, if I collect data from 5 files, I'll get 5 headers.
So I'm looking for a solution to retrieve header with command HDR = NO on Excel SQL query (start at line 2 in each file).
I tried OFFSET command in SQL query but I get an error message.
I also tried to get the row number in the original file but I didn't find the command.
Do you have any idea to help me on this issue?
Many thanks in advance,
BR
Code for information:
Option Explicit
Sub SqlUnionTest()
Dim strConnection As String
Dim strQuery As String
Dim objConnection As Object
Dim objRecordSet As Object
strConnection = _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"User ID=Admin;" & _
"Data Source='" & ThisWorkbook.FullName & "';" & _
"Mode=Read;" & _
"Extended Properties=""Excel 12.0 Macro;"";"
strQuery = _
"SELECT * FROM [Sheet1$] " & _
"IN '" & ThisWorkbook.Path & "\Source1.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=NO;'] " & _
"UNION " & _
"SELECT * FROM [Sheet1$] " & _
"IN '" & ThisWorkbook.Path & "\Source2.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=NO;'] " & _
"UNION " & _
"SELECT * FROM [Sheet1$] " & _
"IN '" & ThisWorkbook.Path & "\Source3.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=NO;'] " & _
"ORDER BY ContactName;"
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open strConnection
Set objRecordSet = objConnection.Execute(strQuery)
RecordSetToWorksheet Sheets(1), objRecordSet
objConnection.Close
End Sub
Sub RecordSetToWorksheet(objSheet As Worksheet, objRecordSet As Object)
Dim i As Long
With objSheet
.Cells.Delete
For i = 1 To objRecordSet.Fields.Count
.Cells(1, i).Value = objRecordSet.Fields(i - 1).Name
Next
.Cells(2, 1).CopyFromRecordset objRecordSet
.Cells.Columns.AutoFit
End With
End Sub
You can specify the starting and ending row while querying the excel file. So Instead of -
SELECT * FROM [Sheet1$]
Use This -
SELECT * FROM [Sheet1$A2:end]
A2 - it will start reading from 2nd row.
end - will read until the sheet has data. So suppose, if you want to only some rows from SHEET1. Use this -
SELECT * FROM [Sheet1$A2:A10]
I am querying Active Directory to list Users and other fields in Access. Is there a way to append my queried results into an existing table? Currently I am trying to use INSERT INTO but having issues with my Object variable not being set or block variable.
Private Sub Command0_Click()
Dim objRecordSet As Object
Dim objCommand As Object
Dim objConnection As Object
Dim dbs As Database
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Sort On") = "whenCreated"
objCommand.CommandText = _
"SELECT Name,Title,PhysicalDeliveryOfficeName,WhenCreated,Mail FROM 'LDAP://OU=Standard Users,OU=Active Users,OU=All Users,DC=contoso,dc=local' WHERE objectCategory='user'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
dbs.Execute " INSERT INTO ADUsers" & "(Name,Title,Site,Created,Email) VALUES " & "(objRecordSet.Fields('Name').Value,objRecordSet.Fields('Title').Value,objRecordSet.Fields('physicalDeliveryOfficeName').Value,objRecordSet.Fields('whenCreated').Value,objRecordSet.Fields('Mail').Value);"
dbs.Close
Debug.Print objRecordSet.Fields("Name").Value; "," & objRecordSet.Fields("Title").Value; "," & objRecordSet.Fields("physicalDeliveryOfficeName").Value; "," & objRecordSet.Fields("whenCreated").Value; "," & objRecordSet.Fields("Mail").Value
objRecordSet.MoveNext
Loop
End Sub
Everything inside doublequotes " is interpreted as string not as code and strings (the values of objRecordSet.Fields("myFieldName").Value) have to be quoted in insert statement.
dim strSQLInsert as String
strSQLInsert = "INSERT INTO ADUsers(Name,Title,Site,Created,Email) VALUES ('" & _
objRecordSet.Fields("Name").Value & "','" & _
objRecordSet.Fields("Title").Value & "','" &
objRecordSet.Fields("physicalDeliveryOfficeName").Value & "','" & _
objRecordSet.Fields("whenCreated").Value & "','" & _
objRecordSet.Fields("Mail").Value & "');"
Debug.Print strSQLInsert
dbs.Execute strSQLInsert
Store your sql statements in a string, then you can check it with Debug.Print.
Consider a parameterized query using querydefs to avoid the need of quotes. Also be sure to initialize the database object which may be your main issue: set dbs = CurrentDb.
...
Dim strSQL As String
Set dbs = CurrentDb
strSQL = "PARAMETERS NameParm TEXT(255), TitleParam TEXT(255), SiteParam TEXT(255)," _
& " CreatedParm Date, EmailParam TEXT(255);" _
& " INSERT INTO ADUsers (Name, Title, Site, Created, Email)" _
& " VALUES ([NameParm], [TitleParam], [SiteParam], [Created], [Email]);"
Do Until objRecordSet.EOF
Set qdef = dbs.CreateQueryDef("", strSQL)
qdef!NameParam = objRecordSet![Name]
qdef!TitleParam = objRecordSet![Title]
qdef!SiteParam = objRecordSet![PhysicalDeliveryOfficeName]
qdef!CreatedParam = objRecordSet![WhenCreated]
qdef!EmailParam = objRecordSet![Mail]
qdef.Execute (dbfailOnError)
Set qdef = Nothing
objRecordSet.MoveNext
Loop
I am trying to update a single record in sql using a recordset I'm Pulling data from one recordset and trying to save it to another table in the database This is the code I have the insert statement runs fine in SQL.
' Opening the connection
cn.ConnectionString = "Provider=SQLOLEDB; Data Source=" & dbLocation & "; Initial Catalog=Posbdat; User Id=sa"
cn.Open
rh.ConnectionString = "Provider=SQLOLEDB; Data Source=" & dbLocation & "; Initial Catalog=Postrans; User Id=sa"
rh.Open
rs.Open "Select Top 1 * from CustomerPoints order by RedemptionDate desc", cn, adModeReadWrite
x.Open " Select Top 1 * from Register_Header order by datetime desc", rh, adModeReadWrite
rt.Open " SELECT top 1 upc FROM Register_Trans INNER JOIN Register_Header ON Register_Trans.trans_no = Register_Header.trans_no Where trans_subtype = 'AP' Order by Register_Trans.datetime desc ", rh, adOpenDynamic
Debug.Print x!emp_no
Debug.Print x!till_no
Debug.Print x.Fields(10)
Debug.Print itemupc
itemupc = rt.Fields(0)
Dim cmd As New ADODB.Recordset
cmd.Open "UPDATE CustomerPoints set emp_no = " & x!emp_no & _
", till_no = " & x!till_no & " purch_amt = " & x!Total & _
", item_redeem = ' " & itemupc & " ' Where RedemptionDate = (Select top 1 * from CustomerPoints order by " & _
"RedemptionDate Desc)", cn, adOpenDynamic
cmd.update
I haven't closed any of the connections or cleaned it up because it won't run without crashing.
It has been a long time but this is how I used to execute update statements:
Dim conTemp As New ADODB.Connection
conTemp.CommandTimeout = mvarconConnection.CommandTimeout
conTemp.ConnectionTimeout = mvarconConnection.ConnectionTimeout
conTemp.CursorLocation = mvarconConnection.CursorLocation
conTemp.Mode = mvarconConnection.Mode
conTemp.ConnectionString = mvarconConnection.ConnectionString
conTemp.Open mvarconConnection.ConnectionString
conTemp.Execute "SET CONCAT_NULL_YIELDS_NULL OFF"
conTemp.Execute "UPDATE CustomerPoints set emp_no = " & x!emp_no & _
", till_no = " & x!till_no & " purch_amt = " & x!Total & _
", item_redeem = ' " & itemupc & " ' Where RedemptionDate = (Select top 1 * from
CustomerPoints order by " & _
"RedemptionDate Desc)"
The mvarconConnection is just an object that stored all of my DB settings, just replace my settings with your own.