runing a query of combinationfield in runtime,how? - ms-access

I have a combination field that contains a query.I want to speed up my access forms hence I want to run the query of this combinationfield in runtime( in VB code) but I dont know how? Would you please show me an example?

if you want a SELECT query then use
Dim recSet As Recordset
recSet = CurrentDb.OpenRecordset("SELECT * FROM table1 WHERE field1=" & Me.myField)
or
recSet = DoCmd.RunSQL("SELECT * FROM table1 WHERE field1=" & Me.myField)
for other commands (DELETE, UPDATE, INSERT,...) use
CurrentDb.Execute "DELETE * FROM table1 WHERE field1=" & Me.myField
or
DoCmd.RunSQL "DELETE * FROM table1 WHERE field1=" & Me.myField

Related

MS Access add/update query result to an existing table base on its ID

I followed the tips by others to produce an access query.
I have two tables. See figure1. And the result is figure2.
Figure1
http://img.libk.info/f1.png http://img.libk.info/f1.png
Figure2
http://img.libk.info/f2.png http://img.libk.info/f2.png
The method to generate the result query is solved in another question.
The query script :
TRANSFORM Nz(Count([number]),0) AS CountValue
SELECT Table1.ID
FROM Table1, Table2
WHERE (((Table2.number) Between [table1].[start] And [table1].[end]))
GROUP BY Table1.ID
PIVOT DatePart("yyyy",[ndate]);
My question is:
Is there anyway to write back the query result to table 1?
I want to add two new columns in table 1. And be able to add or update the query value to the field base on its "ID".
I'm not sure my description is clear or not. Hope you may understand and thanks for your help!
You won't be able to do it directly. However, here are two ways it could be done indirectly.
Method 1: Temp Table
This method is best for a quick-and-dirty one-time solution.
Create a Make-Table query based on your query and use it to make a temporary table.
Use the temporary table joined to [Table 1] to update your two new fields.
Delete the temporary table
Method 2: VBA Routine
This method is best when you want a repeatable method. It's overkill if you're only going to do it once. However, if you want calculated values for every year, you'll need to run it again.
Read the query into a recordset
Loop through the Recordset and for each ID, either
Run a sql statement to update table 1, or
open a second recordset querying by the ID and Edit/Update
Here's a simple version that updates the value for a single year.
Public Sub UpdateAnnualTotal(ByVal nYear As Long)
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim sSQL As String
Dim sId As String
Dim nTotal As Long
Set db = CurrentDb
sSQL = "SELECT [ID],[" & nYear & "_count"] FROM AnnualTotalsQuery"
Set rs = db.OpenRecordset(sSQL)
With rs
Do Until .EOF
sId = .Fields("ID").Value
nTotal = .Fields(nYear & "_count").Value
sSQL = "UPDATE [Table 1] SET [" & nYear & "_count"] = " & nTotal _
& " WHERE [ID] = '" & sId & "'"
db.Execute sSQL
.MoveNext
Loop
.Close
End With
End Sub

Can I have a DoCmd method in IF statement?

I have the following VBA code for a .mdb Access file:
If DoCmd.RunSQL "SELECT DISTINCT Max(wk_ending_dt) FROM d2s_loader_performance" < (Date()-Weekday(Date())) Then
DoCmd.RunSQL "DELETE * FROM d2s_loader_performance_tbl WHERE wk_ending_dt = (Date()-Weekday(Date())-35)"
End If
It then highlights the following text: "SELECT DISTINCT Max(wk_ending_dt) FROM d2s_loader_performance" And gives the error Compile Error: Expected Then or GoTo.
Any ideas? I have a Then at the end of my conditional check, and to my understanding the double quotes are just for the SQL syntax. I'm using this If...Then condition to only allow record deletion if the max table date is less than the previous week's ending date.
You probably need to attack it this way:
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset ("SELECT DISTINCT Max(wk_ending_dt) FROM d2s_loader_performance")
If rec(0) < (Date()-Weekday(Date())) Then
DoCmd.RunSQL "DELETE * FROM d2s_loader_performance_tbl WHERE wk_ending_dt = #" & (Date()-Weekday(Date())-35) & "#"
EndIf
I'm assuming that "(Date()-Weekday(Date())-35)" part is supposed to be a calculation, so you need to surround it with ampersands (&), and dates in Access always need to have pound signs (#) before and after them if they're true Date fields.
The problem is that you can execute only action querys with DoCmd.RunSQL. So, you can't execute Select statement. For more info see this
My approach is to using something like this:
Sub SqlExecute()
Dim db As DAO.Database
Dim rsttemp As DAO.Recordset
Set db = CurrentDB
sql = "SELECT DISTINCT Max(wk_ending_dt) FROM d2s_loader_performance"
Set rsttemp = db.OpenRecordset(sql, dbOpenSnapshot)
If rsttemp(0)<(Date()-Weekday(Date())) Then
DoCmd.RunSQL "DELETE * FROM d2s_loader_performance_tbl WHERE wk_ending_dt #=" & (Date()-Weekday(Date())-35) & "#"
End If
Set rsttemp = Nothing
End Function

MS Access: How do I set up thie Recordset.Filter filter?

I have an issue that I am trying to find a solution for.
I have a table, it looks something like this:
#myTable
id - Number
value - Text
models - Memo
I also have a table that looks something like this:
#myModels
id - Number
model - Text
notes - Memo
The #myTable.models value is a concatenation of different #myModels.model strings concatenated with the '|' character. For instance, it might have ModelA|ModelB|ModelC| or only ModelA|ModelC|
I need to filter the recordset from #myTable based on which model is currently selected. Right now I have something like this:
Dim sql As String
sql = "SELECT * FROM myTable"
Dim rs1 As Recordset
Set rs1 = DBO.Edit (sql)
sql = "SELECT model FROM myModels"
dim rs2 As Recordset
Set rs2 = DBO.Read (sql)
If Not rs2.BOF Then rs2.MoveFirst
While Not rs2.EOF
If Not rs1.BOF Then rs1.MoveFirst
While Not rs1.EOF
Dim models() As String
models = Split(rs1![models], "|")
Dim model As String
For Each model In models
If model = rs2.model Then
'Do some processing
End If
Next model
rs1.MoveNext
Wend
rs2.MoveNext
Wend
I was really hoping that I would be able to perform some type of regex on the query or in the filter, so it would possibly look something like this:
While Not rs2.EOF
rs1.Filter( "Insert Regex Here" )
If Not rs1.BOF Then rs1.MoveFirst
While Not rs1.EOF
' Do Some Processing here
rs1.MoveNext
Wend
rs2.MoveNext
Wend
I guess that my main issue is that the #myModels table has ~ 1000 records and is growing, while the #myTable table has more than 30k records in it. This takes an extremely long time to loop through when trying to loop through each record that many times.
Any solutions would be greatly appreciated.
did you try sql = "SELECT model FROM myModels where criteria"?
not sure what you mean by currently selected model but you can use tempVars to add temporary strings or whatever else you need
perhaps join in your sql?
can you specify in detail where is this model coming from and how its selected
Iterating over records in VBA is generally slower than a single SQL query. Running through a single SQL query would be faster than multiple loops with VBA:
SELECT myTable.*
FROM myTable, myModels
WHERE myTable.models LIKE "%" & myModels.model & "%"
In VBA:
Dim sql As String, rs As Recordset
sql = _
"SELECT * " & _
"FROM myTable, myModels " & _
"WHERE myTable.models LIKE ""*"" & myModels.model & ""*"""
Set rs = dbs.OpenRecordset(sql)
While Not rs.EOF
'Some processing here
Loop
Admittedly, this will still be slow, because this is an outer join, and because we're using the non-optimized LIKE operator.
If instead of the myTable.models field, you can add an intermediate table:
#myTableModels
tableID - number
modelID - number
with proper relationships, the resulting query will be near-instantaneous:
SELECT myTable.*
FROM (myTable
INNER JOIN myTableModels
ON myTable.id = myTableModels.tableID)
INNER JOIN myModels
ON myTableModels.modelID = myModels.ID

How to add a record to table2 from form 1 (tabel1)

When I'm in table 1, form 1 I want to have a button that when clicked adds a record to table 2.
How can this be made possible?
You can run SQL or a query from VBA, for example:
Set db = CurrentDB
sSQL="INSERT INTO Table2 (FKID, Stuff) VALUES (" & Me.ID & ",'" & Me.Stuff & "')"
db.Execute sSQL, dbFailOnError
MsgBox "Records inserted " & db.RecordsAffected
Or if you have built a suitable query:
DoCmd.OpenQuery "QueryName"
Note that if you are adding to a table because you wish to add extra items to a combobox list, search for NotInList, you will find a number of suggestions.
One way (out of many):- in the click event of your button:
currentdb.execute "insert into table2 (col1, col2) select 'some_string', 12345;"

Selecting 2 tables from 2 different databases (ACCESS)

here is the connection i have
strCon="DBQ=" & Server.Mappath("db.mdb") & ";Driver={Microsoft Access Driver (*.mdb)};PWD=password;"
set adoCon=server.createobject("adodb.connection")
adoCon.Open strCon
so in order to work with the 2 databases i have 2 adoCon and when i do the select i select from each db i need
now for the problem...
in this situation i will be able only to get all the info from one and then from the other one. but what i want is to be able to put the together.
db1.tblcats has categories and db2.tblcats has categories and subcategories
so in addition to be able to select both of the together, i need to be able to know what cat is from what db
Step 2 after the big help
this is my code
strSQL = "SELECT name FROM tblcats union " _
& "select name from [MS Access;PWD=pass;DATABASE=" & Server.Mappath("../shop.mdb") & "].tblcats as bcats where bcats.father=50"
rs.CursorType = 3
rs.LockType = 3
rs.Open strSQL, strCon
while not rs.eof
response.write rs("name")&"<br>"
rs.movenext
wend
how can i know what record came from what db? cause i need to act difrently for each one
You can use IN:
SELECT t1.*, t2.*
FROM T1
INNER JOIN
(SELECT * FROM atable
IN 'C:\Docs\DB2.mdb') t2
ON t1.ID=t2.ID
EDIT:
sc = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\docs\other.mdb"
cn.open sc
s="SELECT * FROM t1 INNER JOIN " _
& "[MS Access;PWD=databasePWD;DATABASE=C:\docs\db.mdb].t2 ON t1.ID=t2.ID"
rs.Open s, cn
EDIT 2:
You can use the aliases to identify which database a field is from:
s="SELECT * FROM table1 t INNER JOIN " _
& "[MS Access;PWD=databasePWD;DATABASE=C:\docs\db.mdb].m ON t.ID=m.ID"
msgbox rs.fields("m.code") & " " & rs.fields("t.code")
EDIT 3
Or you can add a virtual field:
SELECT 1 AS "DB", Field, Field FROM ...
UNION ALL
SELECT 2 AS "DB", Field, Field FROM
UNION ALL is usually faster.