I'm using the below code to create a DNS-Less connection to an Oracle DB and this code works fine. Some information has been removed due to its sensitive nature. Again the posted code is working. I'm looking to add the ability to make a table within access. How do I take the query results and place them into a table?
Dim tdf As TableDef
Dim DB As Database
Set DB = CurrentDb
'Rem create link to groups def
Set tdf = DB.CreateTableDef("Sale")
tdf.Connect = "ODBC;Driver={Microsoft ODBC for Oracle};Server=" & ServerName & ";UID=" & UID & ";Pwd=" & PWD & ""
tdf.SourceTableName = "SBOMAST_OWN.SALE"
DB.TableDefs.Append tdf
DB.Close
Set DB = Nothing
Assuming you want to make the table from scratch, you will want to use a make table query, which in VBA, takes the form of SELECT * INTO Target FROM Source. I know with ODBC, you can put the connection string directly into the Target and Source values, eliminating the need for a recordset. Your query would become:
"SELECT * INTO NewAccessTable FROM (" & strConnectionString & ") OracleDBTable"
Check out this article for more information: http://support.microsoft.com/kb/200427
Related
My access 2010 database has super massive bloat. It has gone from 44mb to 282mb in just a few runs of the VBA. Here is what I have set up:
Local tables - these calculate statistics on forms and generally don't move around too much.
Pass through queries - my personal suspect. While viewing a form, if the user clicks on a record I run a pass through query using the record the user clicked on. So user clicked on "joe", pass through query runs with sql string = "select * from sqlserver where name= " &[forms]![myform]![firstname]
After this query runs, my vba DELETES the pass through query, then recreates it after another record is selected. so the user goes back to the list of names, and clicks BRIAN. then my vba deletes the pass through query and creates another one to select all records named brian from sql server, using the same code as above.
Forms - my forms are using the pass through queries as sources.
Is what I'm doing not very smart? How can I build this better to prevent access from exploding in file size? I tried compact and repair, as well as analyze DB performance in access 2010. Any help at all is appreciated, I've been googling access2010 bloat and have read about temptables as well as closing DAO (which I am using, and which I did explicitly close). Thanks!
Here is some code for 1 of the forms i'm using -
Private Sub name_Click()
'set dims
Dim db As DAO.Database
Dim qdExtData As QueryDef
Dim strSQL As String
Dim qdf As DAO.QueryDef
'close form so it will refresh
DoCmd.Close acForm, "myform", acSaveNo
'delete old query so a new one can be created with the same name
For Each qdf In CurrentDb.QueryDefs
If qdf.Name = "QRY_PASS_THROUGH" Then
DoCmd.Close acQuery, "QRY_PASS_THROUGH", acSaveNo
DoCmd.SetWarnings False
DoCmd.DeleteObject acQuery, "QRY_PASS_THROUGH"
DoCmd.SetWarnings True
Exit For
End If
Next
Set db = CurrentDb
'sql for the data
strSQL = "select fields from (table1 inner join table2 on stuff=stuff and stuff=stuff) left join table3 on stuff=stuff and stuff=stuff where flag='P' and table.firstname = " & [Forms]![myform]![firstname]
Set qdExtData = db.CreateQueryDef("QRY_PASS_THROUGH")
'how you connect to odbc
qdExtData.Connect = "ODBC;DSN=server;UID=username;PWD=hunter2;"
qdExtData.SQL = strSQL
DoCmd.OpenForm ("names")
Forms!returns!Auto_Header0.Caption = "Names for " & Me.name & " in year " & Me.year
qdExtData.Close
db.Close
qdf.Close
Set db = Nothing
Set qdf = Nothing
End Sub
There no reason I can think of to not bind the form to a view and use the “where clause” of the open form command. It would eliminate all that code.
You could then simply use:
strWhere = "table.FirstName = '" & me.FirstName & "'"
Docmd.OpenForm "Names”,,,strWhere
Also, it makes little or no sense that a C + R does not return free space. Something else here is seriously wrong.
Also, you really don’t need to delete the query each time. Just assume that the pass-through ALWAYS exists and then use this:
strSQl = “your sql goes here as you have now”
Currentdb.Querydef("MyPass").SQL = strSQL
Docmd.Openform “your form”
The above is all you need. I count about 3 lines of code here that will replace all what you have now. Note that of course the connection string info is saved with the pass-though and does not need to be set or messed with each time.
I would also do a de-compile of your database. I have a short cut setup on all my dev machines so I can just right click to de-compile. Here is some info on de-compile:
http://www.granite.ab.ca/access/decompile.htm
So really, I don’t know why you not using the where clause of the open form? Just bind the form to a SQL view without any conditions. Then use the open form command – you only pull records down the network pipe that match your criteria.
And note how you can stuff your SQL directly into the .SQL property of the query def as above shows – again no need for that delete code and this also means you don’t mess with connection info in code either. Again about 3 lines in total.
I have already referenced other pages for my problem but I still can't get this to work. I feel a bit slow given that I have three examples below and still can't figure this out.
Changing linked table location programatically
Linked table ms access 2010 change connection string
Update an Access linked table to use a UNC path
Here is the code that I am using:
Dim tdf As TableDef
Dim db As Database
Set db = CurrentDb
Set tdf = db.TableDefs("DeviceListT")
tdf.Connect = "ODBC;DATABASE=" & CurrentProject.path _
& "\HarmonicProfileDatabase_be.accdb"
tdf.RefreshLink
The problem is that when I run it a window pops up.
I am not exactly sure what I am supposed to do with that nor do I want it to pop up in the first place as I will be giving the ms access files to someone else and they won't know what to do with this window either.
You are using SQL Server references but linking MS Access. For MS Access, you do not need an ODBC link, just refer to DATABASE:
DBFile = CurrentProject.path & "\HarmonicProfileDatabase_be.accdb
''Check the file exists
strFile = Dir(DBFile)
If strFile <> "" Then
With CurrentDb
For Each tdf In .TableDefs
''Check that this is a linked table
''It can be useful to use table of tables instead
If tdf.Connect Like "*HarmonicProfileDatabase_be.accdb*" Then
tdf.Connect = ";DATABASE=" & DBFile
tdf.RefreshLink
End If
Next
End With
MsgBox "Link HarmonicProfileDatabase_be.accdb"
Else
MsgBox "Problem"
End If
You could also use:
sConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& DBFile & ";Jet OLEDB:Database Password=pw;"
In MS Access 2010, I am building an update query (using the Query Designer).
I would like to pass the name of the column to update as a variable, at run time.
I have tried writing the SQL and running the query in VBA. This seemed like the easiest way... however the SQL to complete the update becomes quite messy. I would prefer to do this in the query builder GUI .
Is it possible?
I have so far tried entering field names into the query builder:
expr1:[field_name]
Although Access prompts me for "Field_name" This results in "Cannot update 'field_name'; field not updateable.
Also, I tried this method:
Expr1: "'" & [field_name] & "'"
which results in "'" & [field_name] & "'" is not a valid name; check for punctuation.. etc
Below is a screen capture the query I am trying to build.
Access' db engine will not allow you to use a parameter as the name of the target field for your UPDATE statement.
If you try a user-defined function instead of a parameter to provide the field name, the result will be the same ... no joy.
It seems the db engine will not resolve object names when it executes a SQL statement. That limitation applies not just to field names, but table names as well. IOW, the following query will fail with an error message that it "cannot find the input table or query 'give me a table name'".
SELECT *
FROM [give me a table name];
While that isn't exactly the same as your situation, I suspect the reason may be. The db engine is too limited about resolving object names when it plans/executes queries.
Perhaps the best method is to use SQL, build your prompts and then assign these values to variables in VBA, then just add the variable value into your SQL.
So something along these lines. Your using Update query but same logic
Dim SQL as string
dim **FieldName** as string
SQL = "Select [table]![" & Chr(34) & **FieldName** & Chr(34) & "] from ........"
Check Here for SQL building tips
I use this method frequently - I know it's a very old post, but hope this helps someone - building on what David said:
Sub CreateQuery
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
Set dbs = CurrentDb
Set qdf = dbs.CreateQueryDef("NameOfNewQuery")
strSQL = "Select " 'notice the space
strSQL = strSQL & "FROM " 'notice the sapce
strSQL = strSQL & "WHERE;"
qdf.SQL = strSQL
qdf.Close
Set qdf = Nothing
Set dbs = Nothing
End Sub
I am using the following code in Access to try to open a recordset:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("fieldHistory")
I consistently get the error "Too few parameters."
fieldHistory is a query with the SQL code as follows:
SELECT Date, User, Type
FROM Inventory
WHERE ((Inventory.Type) In ("Insert","EditTo"));
I have looked into this some - I have found that if I use the code db.OpenRecordset("Select * from Inventory") I do not get an error.
Also, I found this forum which seemed to be on to something but I couldn't understand how to create the appropriate querydef objects to create my query.
http://access.mvps.org/access/queries/qry0013.htm
Thank you very much!
Date, User, and Type are all special words or reserved words in MS Access. DO NOT use them for your field names.
You may have some success by enclosing each of them in brackets but I highly recommend you change the field names instead.
Create a new database.
Open the new database and make sure you have DAO included in the references.
Insert a new standard module, making sure to include Option Explicit in the Declarations section.
Then paste in this code and run it.
Public Sub CreateTableZack()
Dim strSql As String
strSql = "CREATE TABLE tblZack (" & vbNewLine & _
vbTab & "id COUNTER CONSTRAINT pkey PRIMARY KEY," & vbNewLine & _
vbTab & "foo_text TEXT(255)," & vbNewLine & _
vbTab & "date_assigned DATETIME);"
Debug.Print strSql
CurrentProject.Connection.Execute strSql
End Sub
Assuming the table is created successfully, create qryZack with this as its SQL:
SELECT *
FROM tblZack;
Then try your code to open a DAO recordset based on qryZack.
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("qryZack")
Does it work?
If not, your Access installation may be hosed ... you may need to repair or reinstall it. You could also try this on another machine which has Access available, if you can.
If it works with the new database, but not your old one, the old one may be corrupted. Make a backup copy first, then try Compact & Repair.
Another issue is your field names. Date, User and Type are all Access reserved words. See Problem names and reserved words in Access. I can't say those names are causing problems here, but using reserved names for database objects (tables, fields, queries, etc.) can have dramatic consequences ... like it confuses the crap out of Access. So I fastidiously avoid them.
Edit: You should also check the references in your old database. Missing/broken references also confuse the crap out of Access.
Hey.
I have the main access database located on a stand alone PC off the network and i have a access database with linked tables on the network linked back to the stand alone PC. I have linked the tables by creating a network share to the stand alone PC and linking them though a path. Can i set it up so that when the database is opened it automatically updates the linked tables.
Ben
You can. I often find it convenient to use a small check form that runs on start-up (set through start-up options) and checks a variety of things, including linked tables. To this end, I also hold a table of linked tables on the local machine, although a list of linked tables can be obtained by iterating through the TableDefs collection, I think it is slightly safer to keep a list.
The check form can check all links and if a link is broken or missing, either ask the user for a new location or use a fixed location. If no problems are found, the form can close itself and open a menu or other form.
In the case of linking to a linked table, it is possible to get the connection to use from:
CurrentDB.TableDefs("TableName").Connection
Here are some more notes:
Sub RelinkTables(Optional strConnect As String = "")
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL
Dim tdf As DAO.TableDef
On Error GoTo TrapError
Set db = CurrentDb
If strConnect = "" Then
''Where Me.txtNewDataDirectory is a control on the check form
strConnect = "MS Access;PWD=databasepassword;DATABASE=" & Me.txtNewDataDirectory
End If
''Table of tables to be linked with two fields TableName, TableType
Set rs = CurrentDb.OpenRecordset("Select TableName From sysTables " _
& "WHERE TableType = 'LINK'")
Do While Not RS.EOF
''Check if the table is missing
If IsNull(DLookup("[Name]", "MSysObjects", "[Name]='" & rs!TableName & "'")) Then
Set tdf = db.CreateTableDef(RS!TableName, dbAttachSavePWD, _
rs!TableName, strConnect)
''If the table is missing, append it
db.TableDefs.Append tdf
Else
''If it exists, update the connection
db.TableDefs(rs!TableName).Connect = strConnect
End If
db.TableDefs(rs!TableName).RefreshLink
RS.MoveNext
Loop
Set db = Nothing
RS.Close
Set RS = Nothing
Exit_Sub:
Exit Sub
TrapError:
HandleErr Err.Number, Err.Description, "Relink Tables"
End Sub