HI
I want to find a particular field, which exist in tables of a Access database. Is there is any utility to find this?
Yes you can do it VBA code. I have emailed you.
Public Function FindField(fieldname As String)
Dim db As Database
Dim td As TableDef
Dim fd As Field
Set db = DBEngine(0)(0)
db.TableDefs.Refresh
For Each td In db.TableDefs
For Each fd In td.fields
If fieldname = fd.Name Then
Debug.Print td.Name
End If
Next
Next
db.Close
End Function
You can use ADO Schemas:
Function ListTablesContainingField(SelectFieldName) As String
''Tables returned will include linked tables
Dim cn As New ADODB.Connection
Dim rs As ADODB.Recordset
Dim strTempList As String
On Error GoTo Error_Trap
Set cn = CurrentProject.Connection
''Get names of all tables that have a column called <SelectFieldName>
Set rs = cn.OpenSchema(adSchemaColumns, _
Array(Empty, Empty, Empty, SelectFieldName))
''List the tables that have been selected
While Not rs.EOF
''Exclude MS system tables
If Left(rs!Table_Name, 4) <> "MSys" Then
strTempList = strTempList & "," & rs!Table_Name
End If
rs.MoveNext
Wend
ListTablesContainingField = Mid(strTempList, 2)
Exit_Here:
rs.Close
Set cn = Nothing
Exit Function
Error_Trap:
MsgBox Err.Description
Resume Exit_Here
End Function
See also: http://support.microsoft.com/kb/186246
I do a lot of maintenance and integration work in access and a vba module written by Allen Browne totally rocks.
In your immediate window type
?Findfield("myfieldname")
It will search your database (tables, queries, forms, reports) to find where a particular field name is used.
Documentation and code is here http://allenbrowne.com/ser-73.html
Related
I am creating a local MS Access (365) front end application for a SQL Server (Express 2019) DB which is located on a local shared server.
I have a login form that relinks all of the linked tables and views when a user logs in. (This is not primarily for security, so please don't tell me how inadequate this set up is for security - I know.)
Basically, I have a local table in the Access application that lists all the table names that need relinking at login. At login, the current links are deleted, then the code loops through the list of tables and links them according to a connection string that is built in the process, including the UID and the PWD. But when I check on the connection string after login, it doesn't include the login info. My Excel workbook that has a data connection to one of these linked tables cannot connect until I manually edit the string in the Linked Table Manager.
Below is the code for the login process:
Private Sub cmdConnect_Click()
Dim db As Database
Dim tdf As TableDef
Dim rst As Recordset
Dim rst1 As Recordset
Dim strServer As String
Dim strDB As String
Dim strTable As String
Dim strConnect As String
Dim strMsg As String
Dim strPass As String
Dim strPrimary As String
On Error GoTo HandleErr
Set db = CurrentDb
strPass = DLookup("[Password]", "tblUsers", "[User] = '" & Me.txtUser & "'")
If StrComp(Me.txtPwd, strPass, vbBinaryCompare) <> 0 Then
strMsg = "Incorrect Username or password!"
GoTo ExitHere
End If
' Create a recordset to obtain server object names.
Set rst = db.OpenRecordset("tblSQLTables", dbOpenSnapshot)
If rst.EOF Then
strMsg = "There are no tables listed in tblSQLTables."
GoTo ExitHere
End If
'Assign the current user in table
Set rst1 = db.OpenRecordset("tblUsers", dbOpenDynaset, dbSeeChanges)
With rst1
.MoveFirst
Do Until rst1.EOF
.Edit
Select Case !user
Case Me.txtUser
!Current = -1
Case Else
!Current = 0
End Select
.Update
.MoveNext
Loop
End With
strConnect = "ODBC;Driver={ODBC Driver 17 for SQL Server};Trusted_Connection=No;DSN=SQL1;UID=" _
& Me.txtUser & ";PWD=" & Me.txtPwd & ";"
'delete all existing linked tables
Call deleteLinks
' Walk through the recordset and create the links.
Do Until rst.EOF
strServer = rst!SQLServer
strDB = rst!SQLDatabase
strTable = rst!SQLTable
' Create a new TableDef object.
Set tdf = db.CreateTableDef("dbo_" & strTable, 0, "dbo." & strTable, strConnect & "Server=" & strServer & ";Database=" & strDB & ";")
' Set the Connect property to establish the link.
db.TableDefs.Append tdf
Debug.Print tdf.Connect
Set tdf = Nothing
rst.MoveNext
Loop
strMsg = "Tables linked successfully."
rst.Close
Set rst = Nothing
Set tdf = Nothing
Set db = Nothing
DoCmd.Close acForm, Me.name
DoCmd.OpenForm "frmStart"
ExitHere:
MsgBox strMsg, , "Link SQL Tables"
Exit Sub
HandleErr:
Select Case Err
Case Else
strMsg = Err & ": " & Err.Description
Resume ExitHere
End Select
End Sub
Private Sub deleteLinks()
Dim rst As Recordset
Dim db As Database
Dim tdf As TableDef
Set db = CurrentDb
For Each tdf In db.TableDefs
If tdf.name Like "dbo_*" Then
DoCmd.DeleteObject acTable, tdf.name
End If
Next
End Sub
When I look at the immediate window to see the printed tdf.connect it gives me:
ODBC;DRIVER=ODBC Driver 17 for SQL Server;SERVER=RNC1SQL\SQLEXPRESS;UID=****;PWD=*************;Trusted_Connection=No;APP=Microsoft Office;DATABASE=RNCMasterfile;
But when I look at the connection string in the Linked Table Manager, I get the following:
DRIVER=ODBC Driver 17 for SQL Server;SERVER=RNC1SQL\SQLEXPRESS;Trusted_Connection=No;APP=Microsoft Office;DATABASE=RNCMasterfile;
The odd thing is I can access and use the tables in Access, but I have Excel spreadsheets with connections to Access queries based on the linked tables and they don't work if the connection string doesn't contain the login info.
Any ideas to programmatically force the connection string to contain this info?
Try linking your tables using DoCmd.TransferDatabase instead.
DoCmd.TransferDatabase acLink, "ODBC Database", [your_cnn_string], acTable, [source_tbl_name], [linked_table_name], , True
The last option in TranserDatabase is StoreLogin.
I use this in my own apps.
Read about TransferDatabase here.
I'm trying to retrieve and update rows in Excel/SQL and found this script which works but I tried to make it update as soon as I enter the "existencia" value instead of hitting run on the update macro, found the Worksheet change function but I'm not sure how to add it to this macro.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim con As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rst As New ADODB.Recordset
Dim i As Long
Dim vDB As Variant
Dim Ws As Worksheet
con.ConnectionString = "Provider=SQLOLEDB; data source=LAPTOP\SQLEXPRESS;initial catalog=Inventario;Integrated Security=SSPI;"
con.Open
Set cmd.ActiveConnection = con
Set Ws = ActiveSheet
'The assumption is that the data on the Excel sheet is listed from a1 Cell, including fields.
vDB = Ws.Range("a1").CurrentRegion
For i = 2 To UBound(vDB, 1)
cmd.CommandText = "UPDATE Productos SET Existencia='" & vDB(i, 4) & "' WHERE id_cod=" & vDB(i, 1) & " "
cmd.Execute
Next i
con.Close
Set con = Nothing
End Sub
I have used the Worksheet_Change event to do a lot of things, but I have never ever used Worksheet_Change to update data in a SQL Server table. This doesn't really make sense, if you think about it. You can make all kinds of changes in an Excel file, all day long. People do this all the time. When you are totally done with your updates, changes, or whatever, you can push the data to a table in a database. You should not do this intermittently. Otherwise, you will have to do all kinds of cleanup in your database table(s). You don't want to create this kind of overhead for yourself.
I have a copy of an Access database that is meant for importing discontinued product data from a .csv file into a SQL Server database (by using linked tables). When I initiate this import process, I get the following macro error:
I looked up the 2001 Error Number and have seen a few different explanations of it. Mainly, that I need to add the location of the database as a trusted location. I have done that, but that hasn't made a difference.
I noticed I can also see what code the problem occurs in, the "ImportDiscontinued()" function which looks like this:
Public Function ImportDiscontinued()
Dim sImpSpec As String
Dim sImpTable As String
Dim sPath As String
Dim sFile As String
Dim db As Database
Dim rsOption As Recordset
Dim rs As Recordset
Set db = CurrentDb
Set rsOption = db.OpenRecordset("SELECT tblOptions.zValue FROM tblOptions WHERE (((tblOptions.zOption)='ImportPath'));")
sPath = rsOption.Fields("zValue")
Set rsOption = Nothing
If Right(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
sImpSpec = "DiscontinuedItemMaster Import Specification"
sImpTable = "tblDiscontinuedCurrent"
sFile = sPath & "DiscontinuedItemMaster.csv"
DoCmd.SetWarnings False
DoCmd.OpenQuery "dqDiscontinuedCurrent"
DoCmd.OpenQuery "dqObsDiscontinuedDuplicates"
DoCmd.TransferText acImportDelim, sImpSpec, sImpTable, sFile, True
DoCmd.OpenQuery "dqDiscontinuedCurrent_Blanks"
DoCmd.OpenQuery "uqObsDiscontinuedCurrent_SameProdRepl"
DoCmd.OpenQuery "uqObsDiscontinuedCurrent_Trim"
DoCmd.OpenQuery "uqObsDiscontinuedCurrent"
DoCmd.OpenQuery "aqObsDiscontinuedDuplicates"
DoCmd.SetWarnings True
Set rs = db.OpenRecordset("dbo_tmpObsDiscontinued_Duplicates")
If rs.EOF Then
MsgBox "New Discontinued Items Have Imported Successfully! You may now process...", vbInformation + vbOKOnly, "Success!"
Else
MsgBox "Duplicates were found!. They will now be removed...", vbCritical + vbOKOnly, "Error"
DoCmd.RunMacro "mcObsDiscontinuedDuplicates"
End If
Set rsOption = Nothing
Set rs = Nothing
db.Close
End Function
But looking at it, I can't really see where things could be going wrong. I noticed I can set breakpoints, but they don't seem to get hit.
I know that the connection to the SQL Server database is OK because I am initially prompted for credentials and then I am able to view the data through the linked table just fine.
A disclaimer that I am only really familiar with the basics of Access so macros and coding in VBA is all new to me. I typically work with SQL Server databases and programming in C#.
EDIT: Here is the macro "mcObsDiscontinuedImport":
I'm trying to read a particular column value from a SQL result table. I know we use RowCount in c#. But I don’t know how it is done in vb6.0
For example a c# program code:
adapter.Fill(ds);
adapter.Dispose();
con.Close();
rowCount = ds.Tables[0].Rows.Count;// ds is dataset and I read that record set is used instead of dataset
if (rowCount > 1)
{
ab = ds.Tables[0].Rows[0][3].ToString();
ad = ds.Tables[0].Rows[0][8].ToString();
}
In VB6 you have a choice of ADO, DAO or RDO. ADO is newer of the three technologies, and the one MS recommends.
ADO Example
Sub Example()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
' Ready objects for use.
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Connect.
cn.Open "Driver={SQL Server};Server=My_Server_Name;Database=Master;Trusted_Connection=yes;"
' Fetch a recordset.
rs.Open "SELECT TOP 10 Name FROM sys.Objects", cn, adOpenStatic, adLockReadOnly
' Display value, and total recordcount.
MsgBox rs.Fields(0).Value
MsgBox rs.RecordCount
' Close and release objects.
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
The ADO Recordset object has a RecordCount property. Watch out! Certain cursor types do not populate this property. See the link for more on this.
ConnectionStrings.com is a great resource for finding the right connection string for you.
For this example to work you will need to add a reference to the Microsoft ActiveX Data Objects library.
So here's my dilemma I'm attempting to create a macro that runs a query out of sql that located in cell (Sheets("SQL").Range("G1")), and paste the data from that query into Sheets("Data").Range("B1"). I came up with the code below but I keep getting a compile error: User-defined type not defined. Please any insight on what I'm doing wrong will be appreciated.
Sub ConnectSqlServer()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sConnString As String
Dim StrSQL As Variant
Application.ScreenUpdating = False
Application.Cursor = xlWait
Set cnPubs = New ADODB.Connection
Set rsPubs = New ADODB.Recordset
StrSQL = " SET NOCOUNT ON "
' Create the connection string.
sConnString = "Provider=SQLOLEDB; DATA SOURCE=CFS-SERVERSQL;" & _
"Initial Catalog=dmtrans;" & _
"Integrated Security=SSPI;"
' Create the Connection and Recordset objects.
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Open the connection and execute.
conn.Open sConnString
Set rs = conn.Execute(Sheets("SQL").Range("G1"))
' Check we have data.
If Not rs.EOF Then
' Transfer result.
Sheets("Data").Range("B4:S50000").ClearContents
Sheets(Data).Range("b4").CopyFromRecordset rs
' Close the recordset
rs.Close
Else
MsgBox "Error: No records returned.", vbCritical
End If
' Clean up
If CBool(conn.State And adStateOpen) Then conn.Close
Set conn = Nothing
Set rs = Nothing
End Sub
You probably did not set the reference for your ADODB objects.
You can either do this with early binding:
(Don't know the names exactly. I am using a german Excel)
Extras - References: Add the reference Microsoft ActiveX Data Objects vXXX with a click in the checkbox to your project.
Or you can do this via late binding. In this case you must declare your variable as Object and instantiate it via CreateObject. Please find a related question here: Excel VBA: Late binding reference