I have a VBA procedure that uses
DoCmd.RunCommand acCmdNewObjectDesignTable
to create a table. When the table is defined it then uses
DoCmd.RunCommand acCmdNewObjectForm
to create a form based on the table previously created.
How to delay creatng the form until after the table has been defined?
It was suggested that I check for the existence of the TDF after running DoCmd to define the table. The questions still is: How to delay checking until after DoCmd completes?
While VBA is not multi-threaded, "DoCmd" is.
You can get the name by comparing AllTables before and after the create.
Related
I have to create forms in ms access with a database linked from postgresql.
The forms need to show functionalities such as delete record, and this is where my problem is. I have created a button with a delete command:
Private Sub Delete_Click()
If MsgBox("Are you sure?", vbYesNoCancel) <> vbYes Then
Exit Sub
End If
DoCmd.RunCommand acCmdDeleteRecord
End Sub
However when I press it, the command gets cancelled and comes up with a 2501 runtime error.
I have only just started using ms access and any kind of commands so I'm unsure how to fix this issue.
I haven't tried anything as no one else seemed to have this issue.
Generally this means that the underlying linked table does not contain enough information about the index scheme of the table to know how to formulate a DELETE statement. Specifically, it does not understand what the primary key is so that it can generate a DELETE statement that only deletes a single row.
You can verify if this is your issue by opening the Linked Table itself, highlighting the row, and pressing delete. If the row cannot be deleted from the table, you won't be able to delete it from a form based on it.
If this is the case, to solve it, right click the table and run the Linked Table Manager. When relinking the table, if Access needs more information about the index schema it will prompt for it. Help it by selecting the column(s) that comprise the primary key. It will cache this information along with the linked table and you should be able to delete the current row from your form.
Another approach would be to create a DELETE Query that references the ID in the form in the WHERE condition (i.e., Forms!MyForm!ThePKFieldName). Then, in your code behind the button, replace the
DoCmd.RunCommand acCmdDeleteRecord
with
DoCmd.OpenQuery "qryYourQuery"
See this documentation: https://learn.microsoft.com/en-us/office/vba/api/access.docmd.openquery
If this still does not work, your ODBC driver may need to be updated, or you can use an alternative driver.
I would like to maintain a system for uploading data through Excel to SQL Server with ADO method. The process consists of two steps:
the raw data is inserted to temporary table, say dbo.TableTemp
the raw data is processed with a stored procedure and inserted to a dbo.GoodTable
delete from dbo.TableTemp at the end of stored procedure
Is there any way to be sure that the activities of two users not overlap? For example the delete from dbo.TableTemp of user1 will not be executed after user2 inserts data and before the data are processed?
Update. Unluckily I have not been successful with #temp tables. They seem to be too much temporary and when I try to insert data into them #temps already do not exist. For uploading data I use the variation of code by Sergey Vaselenko downloaded from here: http://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm#Excel Data Export to SQL Server using ADO
In the Sergey's solution it is possible to create table by stored procedure prior to inserting the data in step 1. But when I create #temp table with stored procedure, it vanishes at the end of procedure, so I cannot insert data to it. Any help please?
Use temporary tables #TableTemp. Those are specific for each session and thus would not overlap.
There are two types of temporary tables: local and global. They differ
from each other in their names, their visibility, and their
availability. Local temporary tables have a single number sign (#) as
the first character of their names; they are visible only to the
current connection for the user, and they are deleted when the user
disconnects from the instance of SQL Server. Global temporary tables
have two number signs (##) as the first characters of their names;
they are visible to any user after they are created, and they are
deleted when all users referencing the table disconnect from the
instance of SQL Server.
Update. Looks like this particular Excel-SQL Server Import-Export using VBA use separate functions to create table and upload the data each opening and closing own connection. From SQL Server perspective those functions operate in different sessions and thus temporary tables do not persist. I think this solution can be rewritten to use single connection to create temporary table, populate, process the data and output the results into permanent table.
You might also find useful this question: How do I make an ADODB.Connection Persistent in VBA in Excel? In particular - Kevin Pope's answer suggesting the use of global connection variable opened and closed with the workbook itself:
Global dbConnPublic As ADODB.Connection
In the "ThisWorkbook" object:
Private Sub Workbook_Open()
Set dbConnPublic = openDBConn() 'Or whatever your DB connection function is called
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
dbConnPublic.Close
End Sub
Another approach - use TABLE variable. From MSDN
CREATE #AddedValues TABLE (ID INT, SomeValue VARCHAR(50))
Then use it normally as tables in the query.
INSERT INTO #AddedValues (ID, SomeValue) VALUES (1, 'Test');
SELECT ID FROM #AddedValues WHERE SomeValue = 'Test';
Table variable's scope limited to the batch. So you can be sure that other user or even same user will not access it from another batch.
From MSDN
A table variable behaves like a local variable. It has a well-defined
scope. This is the function, stored procedure, or batch that it is
declared in.
Instead of using a Temp-Table in the user database you can put it in the temp db. Prefix the tablename in a CREATE TABLE Statement with # to create it in tempdb.
For example
CREATE TABLE #TableTemp (....)
Only the session that creates the temp table has access to it and SQL Server deletes the table automatically.
I created a table in MS-Access 2010 by running the following script on SQL server 2008
SELECT * into qryInstrumentInterfacelog FROM tblInstrumentInterfaceLog
qryInstrumentInterface is used to populate a subform on the main form. After a "Process" button is pressed, files are read in and stored in the database. tblInstrumentInterface will be inserted with a new record everytime a new file is read in. My problem is qryInstrumentInterfacelog will not update with tblInstrumentInterfaceLog, it will just keep the same data it had when the script was first ran on the server. I have tried different methods to requery the subform but I realized the subform had no issues it was the actual table that wasn't changing. How can I get qryInstrumentInterfacelog to be dynamic and update as tblInstrumentInterfaceLog updates? Is my SQL code wrong?
Well, one important concern is that, indeed, you cannot repeat the query as written.
"Select... into" creates a new table only. It does not insert/append to such a table.
So if you are really calling that a second time, it is probably erroring out.
If you really want to drop and replace the table, make sure to call an explicit "Drop Table" in advance of your "Select...Into".
--
A typical pattern, in SQL Server t-sql, is
if object_id('*your_table_name*') is not null
drop table *your_table_name*
;
*...your select...into*
I am creating a table from an excel file then querying that table. Once I'm done with the table, I would like to drop it. However I'm getting the error
"Database engine could not lock table because "TableName" it is already in use by another program or process.
This is a logical error but I'm not sure how to close the table in VBA? I tried CurrentDb.Close. Is there. I assume there's a way to close it since it'd be in the same session? I'm using the following to drop the table:
db.Execute "DROP TABLE TableName", dbFailOnError
Is it possible to delete the table or do I have to settle for only deleting the rows?
T hank you!
You should be able to drop the table like you tried. The table is locked if you have some open recordsets on it. Look for not closed connections to this table.
This is definitly a problem in your code.
Prior to the DROP statement, the recordset may need closed or Set RecordSet = Nothing works.
I need to create a saved MS Access query from within my VB.net program using OleDb. But before I create the query I need to check and see if it already exists in the database. If it does exist I want to update it. How do I check for an existing query in MS Access using OleDb?
"If it does exist I want to update it."
Based on the comment discussion, I understand you will execute a statement on the OleDB connection to create the query. (In Access parlance, a QueryDef object.)
When the query does not already exist, the execute succeeds and you're done.
If the query does exist, the execute attempt will throw an error which you will trap in your VB.Net code. At that point, you want to revise the existing query. Unfortunately, I don't know any way to alter an existing query with OleDb. You can however discard the existing query and re-execute your statement to create the new version.
You can execute an Access DDL statement to discard the existing query. One of these two versions will do what you need:
DROP VIEW YourQueryNameHere;
DROP PROCEDURE YourQueryNameHere;
The first is for plain SELECT queries. The second is for what Access calls "action queries": INSERT; UPDATE; DELETE. A "make table" query (SELECT <field list> INTO NewTable FROM ...) also falls into the second (PROCEDURE) category as I recall (check to confirm if you need it). I think a SELECT query with PARAMETERS also falls into that second category (check if needed).
Note this is a only a suggested direction. I can't offer you VB.Net code. And I'm hopeful you know or can figure how to do the required error-handling in VB.Net.