Access: How to find a field in a whole database? - database

I have an access database with many tables. I am looking for a field which may or may not exist in one or many of the tables. How do I check if it exists or not? (without querying each table of course)

There is a schema for fields:
Set cn = CurrentProject.Connection
SelectFieldName = "SomeFieldName"
'Get names of all tables that have a column = SelectFieldName '
Set rs = cn.OpenSchema(adSchemaColumns, _
Array(Empty, Empty, Empty, SelectFieldName))
From: MS Access: How to bypass/suppress an error?

If you really do not want to open any table, a solution is to use the tabledefs collection of the database object. Each tabledef item has its own fields collection that you can browse. It would give something like that:
Public function findFieldInDatabase(p_myFieldName)
dim db as database, _
tb as tabledef, _
fd as field
set db = currentDb
for each tb in db.tabledefs
for each fd in tb.fields
if fd.name = p_myFieldName then
debug.print tb.name, fd.name
end if
next fd
next tb
set fd = nothing
set tb = nothing
set db = nothing
end function
This code could be easily adapted to accept an optional p_myTableName as an argument to limit the search to a table/range of tables.

Here's what I would do if I wanted to see if a particular column (identified in strSearch) in a particular table.
Public Sub search()
Dim db As Database
Dim strSearch As String
Dim strSQL As String
Dim rsResults As Recordset
Dim i As Integer
Dim cols As Integer
strSearch = "a3"
Set db = CurrentDb
strSQL = "select * from bar"
Set rsResults = db.OpenRecordset(strSQL, dbOpenDynaset, dbReadOnly)
If Not rsResults.BOF Then
rsResults.MoveFirst
End If
cols = rsResults.Fields.Count - 1 ' -1 because we start counting cols at 0
For i = 0 To cols
If rsResults(i).Name = strSearch Then
MsgBox "Found the seach string"
End If
Next
MsgBox "end of script"
End Sub
Now I know you don't want to write one of those for each table. So the next thing to do would be to loop through all the tables. You can find a list of all the tables with the following SQL
SELECT
name
FROM
MSysObjects
WHERE
(Left([Name],1)<>"~")
AND (Left([Name],4) <> "MSys")
AND ([Type] In (1, 4, 6))
Connecting these two pieces up together, I'll leave as an exercise for the student :)

Here's how you access the table schema in MS Access using VBScript:
TestData = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=c:\somefolder\YOURDB.mdb"
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open TestData
Set rs = Conn.OpenSchema(4)
do until Rs.eof
tn = RS("TABLE_NAME")
fn = RS("COLUMN_NAME")
' your script goes here
loop

Here you go:
Public Function fTableExists(ByVal vstrTable As String) As Boolean
Dim rs As ADODB.Recordset
Set rs = CurrentProject.Connection.OpenSchema( _
adschematables, Array(Empty, Empty, vstrTable))
fTableExists = Not rs.EOF
rs.Close
Set rs = Nothing
End Function
Public Function fColumnExists(ByVal vstrTable As String, _
ByVal vstrColumn As String) As Boolean
Dim rs As ADODB.Recordset
Set rs = CurrentProject.Connection.OpenSchema(adSchemaColumns, _
Array(Empty, Empty, vstrTable, vstrColumn))
fColumnExists = Not rs.EOF
rs.Close
Set rs = Nothing
End Function

MSSQL
Looking for ADDRESS1 column:
select so.name from sysobjects so
where so.id in (select sc.id from syscolumns sc where name like 'ADDRESS1')
ORACLE
http://en.wikipedia.org/wiki/Oracle_metadata
Google will find the syntax for other DBs...

What type of database is it? If it's SQL Server you can try this:
SELECT * FROM sysobjects WHERE xtype = 'U' AND name = 'myTable'
But since it's the column you're looking for and not a table (thanks Brian), try this:
SELECT
DISTINCT
so.[name] AS 'Table',
sc.[name] AS 'Column'
FROM
syscolumns sc
JOIN
sysobjects so
ON
so.id = sc.id
WHERE
sc.[name] = 'myTable'

Related

Using select query on access database

first i was trying to use execute with select query which returns error type mismatch. then after reading some toturials i found out that openrecordset is the trick.
now i am having issue with openrecordset as it is just returning the query and not the selected value. below is my code:
Dim sql As String
Dim rs As DAO.Recordset
' this will loop through each cell in column I until end
For x = 1 To NumRows
sql = "select Email from Salesforce where ID =" & ActiveCell.Value
Set rs = oDB.OpenRecordset(sql, dbOpenDynaset)
ActiveCell.Offset(0, 13).Value = rs
so ActiveCell.Offset(0, 13).Value = sql is just inserting the select Email from Salesforce where ID equals ActiveCell.Value
try using:
ActiveCell.Offset(0, 13).CopyFromRecordset rs

Extract Data from Sql and display to excel using vba

I am trying to join data from two sql tables. Table1 should have columns FileID, AccName, number,ut _score,uw_score
Table 2 should have columns FileID , label, data(contains y/N answers) and AdditionalComments. There are list of questions displayed under column Label. I need to look into last three questions(under the column LABEL) and post the result only if the answers are No
Both these tables can be identified with the unique file id, that is associated with every accountname. So I need to join the table that has only the columns as mentioned above.
Option Explicit
Sub GetDataFromADO()
'Declare variables'
Dim objMyConn As ADODB.Connection
Dim objMyCmd As ADODB.Command
Dim objMyRecordset As ADODB.Recordset
Dim iCols As Integer
Dim tbl As ListObject
Set objMyConn = New ADODB.Connection
Set objMyCmd = New ADODB.Command
Set objMyRecordset = New ADODB.Recordset
'Open Connection'
objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source= .;Initial Catalog=.;Trusted_connection=Yes;Integrated Security=SSPI;"
objMyConn.Open
'Dim sSqL As String
'Set objMyCmd.ActiveConnection = objMyConn
'sSqL = "Select FileID, AccName, number,ut _score,uw_score from AUT.dbo.LIST"
'objMyConn.Execute sSqL
'Set and Excecute SQL Command'
Dim u As String
Set objMyCmd.ActiveConnection = objMyConn
objMyCmd.CommandText = "select AccName, Underwriter, Auditor,UT_Score,Underwriter_Score from Actuarial.dbo.Audit_Checklist"
objMyCmd.CommandText = "Select Label, Data, AdditinalComments from Actuarial.dbo.List_data"
objMyCmd.CommandType = adCmdText
objMyCmd.Execute
'Open Recordset'
Set objMyRecordset.Source = objMyCmd
objMyRecordset.Open
For iCols = 0 To objMyRecordset.Fields.Count - 1
Worksheets("Data").Cells(1, iCols + 1).Value = objMyRecordset.Fields(iCols).name
Next
'Copy Data to Excel'
Worksheets("Data").Range("A2").CopyFromRecordset objMyRecordset
End Sub
Here is the sql query, that I need to include conditions to select last 6 values from the Label column of table 2. Kindly apologize for the naive where clause that i used. Appreciate any help on this !
SELECT Reports.dbo.tbl1.AccName,Reports.dbo.tbl1.Underwriter,
Reports.dbo.tbl1.Auditor, Reports.dbo.tbl1.UT_Score,
Reports.dbo.tbl1.Underwriter_Score, Reports.dbo.tbl2.Label,Reports.dbo.tbl2.Data, Reports.dbo.tbl2.AdditinalComments
FROM Reports.dbo.tbl1
INNER JOIN Reports.dbo.tbl2
ON Reports.dbo.tbl1.FileID=Reports.dbo.tbl2.FileID;
Where Reports.dbo.tbl2.Label='Is it profitable?' OR 'When is effective date expiring ? ' OR 'Did the community accept?';
**Output that I get now **
Expected Result

ListView VB6 and SQL-SERVER, can someone look at my code?

I posted a question asking to help with populating ListView in vb6 with data from SQL-SERVER. So I was able to do that. I'm loading the names of sports, and have ID assigned to each value. Here's the code:
lvwExpenditures.ListItems.Clear
With lvwExpenditures
.FullRowSelect = True
.View = lvwReport
.LabelEdit = lvwManual
.ColumnHeaders.Add , "FldName", "Expense", 2200
.ColumnHeaders.Add , "ID", "ID", 0
End With
g_strSQL = "Select FldName, ID, Label, SortOrder from dbo.tblText_References where fldname ='expenditureitems'"
rs.Open g_strSQL, g_cnDatabase, adOpenStatic
Debug.Print g_strSQL
With rs
Do While Not .EOF
Set lvwItem = lvwExpenditures.ListItems.Add(, , .Fields("Label").Value)
lvwItem.SubItems(1) = .Fields("ID").Value 'Populate Date column
.MoveNext
Loop
End With
Set rs = Nothing
So now, I need to let the user select multiple items from the ListView if they so desire. I did it with checkboxes, but I'm trying to do this without them. Also, if a user selects multiple items, what would my Insert statement look like. I would only need to save the ID's associated with the ids, and concatonate them. Thanks!
dim g_strSQL as string
g_strSQL = "SELECT ID, Desc FROM refTest_Insurance Where statuscode = 'a' ORDER BY InsuranceID ASC"
Debug.Print g_strSQL
Dim conn As ADODB.Connection
Dim g_RS As ADODB.Recordset
' db_file contains the Access database's file name.
' Open a connection.
Set conn = New ADODB.Connection
conn.ConnectionString = "Your connection string here"
conn.Open
' Get the records.
Set g_RS = conn.Execute(g_strSQL, , adCmdText)
'Set URLs = New Collection
Do While Not g_RS.EOF
List1.AddItem g_RS!Desc
'URLs.Add CStr(g_RS!Id)
g_RS.MoveNext
Loop
' Close the recordset and connection.
g_RS.Close
conn.Close

Error on opening qd.openrecordset

What is wrong in this sample ? It breaks where indicated, even while the tbl name provided is the one of a perfectly working linked table.
Sub showLinked(tbl As String)
'tbl is the name of an existing local linked table (SQL Server)'
Dim db As DAO.Database, rs As DAO.Recordset
Dim qd As QueryDef
Set db = CurrentDb
With db.TableDefs(tbl)
Debug.Print .Name, .SourceTableName, .Connect
Set qd = db.CreateQueryDef("")
qd.Connect = .Connect
qd.SQL = "select 1 xxx from " & .SourceTableName
qd.ReturnsRecords = True
Set rs = qd.OpenRecordset() 'breaks here: error 3146 - "ODBC--call failed"
Debug.Print "test connection:", rs.Fields(0)
End With
End Sub
Found the culprit: I was testing my function on an Access table called Data_Archive_Transaction and its SourceTableName is Data_Archive.Transaction (not my name, I promise).
Since Transaction is a reserved word, in a SELECT it must be surrounded with brackets: Data_Archive.[Transaction].
I tried with another table with a more normal name and it worked fine.

MS Access - Linked Tables - DB Owner / Sysadmin

we have a problem with the access linked table wizard. We would like to transfer access tables to an sql server and then link the tables. We would like to have the option that multiple users can do this. Currently we discover that it is only possible to link tables successfully if we use an sql account with sysadmin rights or if the sql user is the owner of the destination database.
Is there a way to enable users creating linked tables without having sysadmin rights and being the owner of the destination database? I thought it would be possible to create linked tables if I use an sql user with the db_owner role assigned for the destination db, but this does not work.
Please help me.
Thank you in advance.
Kind regards
Florian
This answer was long in coming. I modified the code from here and changed it to copy from a local table to a table in SQL Server.
Public Sub CopySchemaAndData_ADOX(ByVal sourceTableName As String, ByVal destinationTableName As String)
On Error GoTo Err_Handler
Dim cn As ADODB.Connection
Dim cat As ADOX.Catalog
Dim cnSQL As ADODB.Connection
Dim catSQL As ADOX.Catalog
Dim sourceTable As ADOX.Table
Dim destinationTable As ADOX.Table
Set cnSQL = New ADODB.Connection
'Set cnSQL = CurrentProject.Connection
cnSQL.Provider = "MSDASQL"
cnSQL.ConnectionString = gstrOLEDBConnection 'put your connection string here. the user needs to be able to create tables on the database
cnSQL.Open
Set catSQL = New ADOX.Catalog
Set catSQL.ActiveConnection = cnSQL
Set destinationTable = New ADOX.Table
destinationTable.Name = destinationTableName
Set cn = CurrentProject.Connection
Set cat = New ADOX.Catalog
Set cat.ActiveConnection = cn
Set sourceTable = cat.Tables(sourceTableName)
Dim col As ADOX.Column
For Each col In sourceTable.Columns
Dim newCol As ADOX.Column
Set newCol = New ADOX.Column
With newCol
.Name = col.Name
.Attributes = col.Attributes
.DefinedSize = col.DefinedSize
.NumericScale = col.NumericScale
.Precision = col.Precision
.Type = col.Type
End With
destinationTable.Columns.Append newCol
Next col
Dim key As ADOX.key
Dim newKey As ADOX.key
Dim KeyCol As ADOX.Column
Dim newKeyCol As ADOX.Column
For Each key In sourceTable.keys
Set newKey = New ADOX.key
newKey.Name = key.Name
For Each KeyCol In key.Columns
Set newKeyCol = destinationTable.Columns(KeyCol.Name)
newKey.Columns.Append (newKeyCol)
Next KeyCol
destinationTable.keys.Append newKey
Next key
catSQL.Tables.Append destinationTable
'To do...
'Link the new sql table
'Finally, copy data from source to destination table
'Dim sql As String
'sql = "INSERT INTO " & destinationTableName & " SELECT * FROM " & sourceTableName
'CurrentDb.Execute sql
Err_Handler:
Set cat = Nothing
Set catSQL = Nothing
Set key = Nothing
Set col = Nothing
Set sourceTable = Nothing
Set destinationTable = Nothing
Set cnSQL = Nothing
Set cn = Nothing
If Err.Number <> 0 Then
msgBox Err.Number & ": " & Err.Description, vbCritical, Err.Source
End If
End Sub

Resources