How to count number of fields in a table? - ms-access

I am trying to count number of fields in a table in Access 2010. Do I need a vb script?

You can retrieve the number of fields in a table from the .Count property of the TableDef Fields collection. Here is an Immediate window example (Ctrl+g will take you there) ...
? CurrentDb.TableDefs("tblFoo").Fields.Count
13
If you actually meant the number of rows instead of fields, you can use the TableDef RecordCount property or DCount.
? CurrentDb.TableDefs("tblFoo").RecordCount
11
? DCount("*", "tblFoo")
11

Using a query:
'To get the record count
SELECT Count(*) FROM MyTable
In DAO it would look like:
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT * FROM MyTable")
rst.MoveLast
'To get the record count
MsgBox ("You have " & rst.RecordCount & " records in this table")
'To get the field count
MsgBox ("You have " & rst.Fields.Count & " fields in this table")
Note, it is important to perform the MoveLast before getting the RecordCount.
In ADO it would look like:
Set conn = Server.CreateObject("ADODB.Connection")
conn.Provider = "Microsoft.Jet.OLEDB.4.0"
conn.Open(Server.Mappath("MyDatabaseName.mdb"))
Set rst = Server.CreateObject("ADODB.recordset")
rst.Open "SELECT * FROM MyTable", conn
'To get the record count
If rst.Supports(adApproxPosition) = True Then _
MsgBox ("You have " & rst.RecordCount & " records in this table")
'To get the field count
MsgBox ("You have " & rst.Fields.Count & " fields in this table")

Quick and easy method: Export the table to Excel and highlight row 1 to get number of columns.

Related

VB6, MS Access, DAO - Display all records WHERE column-name IS NOT NULL

I need a bit of help with this, so what I am trying to do is to display all records WHERE column-name IS NOT NULL. What I have is:
Dim rs As Recordset
Dim sqlStr As String
Set WS = DBEngine.Workspaces(0)
DbFile = (App.Path & "\mydb.mdb")
strSql = "SELECT * FROM MyDatabaseName"
Set rs = db.OpenRecordset(strSql)
rs.MoveFirst
Do While Not rs.EOF
lblResult.Caption = ("cust Name: " & rs!SurName & " cust Surname: " & rs!FirstName)
rs.MoveNext
Loop
MsgBox ("End ")
What I have tried is
strSql = "SELECT * FROM MyDatabaseName WHERE column-name IS NOT NULL"
But I get an error 3131. Any help is appreciated. Also how can I display the result in a ListBox insted of Label.
Simple fix: enclose column names in square brackets when using special characters, like the - substraction operator:
strSql = "SELECT * FROM MyDatabaseName WHERE [column-name] IS NOT NULL"
The rest of your SQL seems valid.
If you want a list box with the results of this query as the list, just set its row source equal to this query, and set its row source type equal to Table/Query. No need for any VBA.
If you want to put everything in a label, use:
Do While Not rs.EOF
lblResult.Caption = lblResult.Caption & "cust Name: " & rs!SurName & " cust Surname: " & rs!FirstName & VbCrLf
rs.MoveNext
Loop

Access VBA - compare records from tables

I have two tables that I wish to compare records - based on a field values. Here is what I tried :
Dim RCount As Long
Dim Rst As Recordset
Dim Rst1 As Recordset
Dim f As Field
'Current Record set
Set Rst = CurrentDb.OpenRecordset("Table1")
Set Rst1 = CurrentDb.OpenRecordset("Table2")
With Rst
For Each f In Rst1.Fields
RCount = DCount("FieldFromTable1", "Table1", "[FieldFromTable1]='" & Me.[FieldFromTable2].Value & "'")
If RCount > 0 Then
Me.Checkbox1.Value = True
End If
Next f
End With
Rst.Close
Rst1.Close
Here is my updated question, something like that I'm trying to accomplish. But still this code cycles only through currently selected record in my Table2 form.
Following on from my comment. You can use recordcounts to see if there is a record that exists and matches. You could use the following query to see if a record exists:
dim rst as recordset
dim varSQL as string
varSQL = "SELECT [fieldfromtable1] FROM Table1 WHERE [fieldfromtable1] ='" & [fieldfromtable2].value & "'"
Set Rst = CurrentDb.OpenRecordset(varSQL)
If rst.recordcount = 1 then
MsgBox "Fields have matching values !"
End If
rst.close
You could replace the =1 with >0.
Alternatively, I think you can use dcount() function which would be something like:
dim RCount as long
Rcount = dcount("fieldFromTable1","table1", "[fieldFromTable1]='" & me.[FieldFromTable2].value & "'")
if Rcount > 0 then
MsgBox "Fields have matching values !"
end if
again, you can use >0 or =1 im not sure which is most appropriate for your situation.
Edit
the following query can be performed to update the checkbox, but this isn't at form level
UPDATE table1 INNER JOIN table2 ON table1.[fieldfromtable1] = table2.[fieldfromtable2] SET table1.[checkboxField] = True
WHERE table2.[fieldfromtable2]= table1.[fieldFromtable1]
I haven't really consider an option to just UPDATE records in tables. Thsi is what It worked for me. I was just trying to set Checkbox to TRUE when record from Table1 meets criteria in Table2. A simple UPDATE solved the problem:
Dim SQL As String
niz = " UPDATE Table2" & _
" INNER JOIN Table1" & _
" ON Table1.FieldFromTable1=Table2.FieldFromTable2" & _
" SET Table2.Checkbox1=True"
DoCmd.SetWarnings False
DoCmd.RunSQL niz
DoCmd.Requery
DoCmd.SetWarnings True

DAO.Recordset.RecordCount property not working as expected

I am running a query from input from a form. It is to extract records from 1 table, where the table is joined to 3 others.
It does successfully extract the record. In this case there is only 1 record and the query does find it.
The problem is that every time I run this code, I get one more RecordCount.
So the first time I run it, the RecordCount is 1 and debug.print gives me the correct information. The second time I run it, the RecordCount is 2 and debug.print gives me the correct information but twice. The third time ... 3 and 3, etc.
It doesn't matter if I close the form (from which I get my variables) and reload it. The number keeps climbing. I closed Access and reopened it and the number keeps climbing - it didn't reset to 1 record found.
The query selects records depending on a ProductID where the (qtyordered - qtyproduced > 0) and the records are sorted by priority of the customers.
Dim rs As DAO.Recordset
Dim db As DAO.Database
Dim findCSQL As String
findCSQL = "SELECT tblWarehouseTransfers.WTRProductID, tblOrderDetails.ODEPriority, tblOrderDetails.ODEQuantityOrdered, " _
& " tblOrderDetails.ODEQtyProduced, tblCustomers.CompanyName " _
& " FROM tblCustomers INNER JOIN (tblOrders INNER JOIN (tblWarehouseTransfers INNER JOIN tblOrderDetails " _
& " ON tblWarehouseTransfers.WTRProductID = tblOrderDetails.ODEProductFK) " _
& " ON tblOrders.ORDOrderID = tblOrderDetails.ODEOrderID) ON tblCustomers.ID = tblOrders.ORDCustomerID " _
& " WHERE (((tblWarehouseTransfers.WTRProductID) = " & Chr$(34) & Me!cboTransferProductID & Chr$(34) & ")) " _
& " AND ((tblOrderDetails.ODEQuantityOrdered - tblOrderDetails.ODEQtyProduced)> 0) " _
& " ORDER BY tblOrderDetails.ODEPriority "
Set rs = db.OpenRecordset(findCSQL)
rs.MoveFirst
Debug.Print rs.RecordCount
Do While Not rs.EOF
Debug.Print ("product ID: " & rs!WTRProductID & " qty ordered: " & rs!ODEQuantityOrdered & " customer name: " & rs!CompanyName)
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
How can I empty the recordset and start fresh each time the subroutine is run?
My memory might be off since it's been a long time since I've worked with RecordSets, but I think you had to traverse the records before the RecordCount property gave you the correct information.
So try it this way:
rs.MoveLast
Debug.Print rs.RecordCount
rs.MoveFirst
From How to: Count the Number of Records in a DAO Recordset
The value of the RecordCount property equals the number of records that have actually been accessed.

Check if a column exists in a pivot query

I have a pivot query I need to loop through and add to another temporary table. The pivot query is a sum of the different statuses found. The statuses are Early, Late, and On-Time. Based on what the user selects, not all of the statuses are present. So when I run the following:
Set rs1 = CurrentDb.OpenRecordset("MyReceivingOnTimeDeliverySummary", dbOpenDynaset)
Set rs = CurrentDb.OpenRecordset("TRANSFORM Sum(recvqty) AS SumOfrecvqty " & _
"SELECT supname, Sum(recvqty) AS TotalReceivedQty " & _
"FROM MyReceivingOnTimeDeliveryDetail " & _
"GROUP BY supname " & _
"PIVOT Status", dbOpenDynaset)
If (rs.RecordCount <> 0) Then
rs.MoveFirst
Do While rs.EOF <> True
rs1.AddNew
rs1.Fields("[supname]").value = rs.Fields("[supname]").value
rs1.Fields("[TotalReceivedQty]").value = rs.Fields("[TotalReceivedQty]").value
rs1.Fields("[Early]").value = rs.Fields("[Early]").value
rs1.Fields("[Late]").value = rs.Fields("[Late]").value
rs1.Fields("[OnTime]").value = rs.Fields("[On-Time]").value
rs1.Update
rs.MoveNext
Loop
End If
If one of the statuses isn't in the results of the query then I will get an error where I am adding that value to the MyReceivingOnTimeDeliverySummary table.
How do I test to for each status and if they are not there then add as 0?
You should be avoiding recordsets for simple operations, like copying with small, uniform changes, in this case. But good news: this makes everything easier!
First, use the SQL statement you already have to create a query.
Dim db As Database
Set db= CurrentDb
db.CreateQueryDef "qry1", "sqltext"
Then, from that query, SELECT INTO (or INSERT INTO) your summary table.
db.Execute "SELECT * INTO MyReceivingOnTimeDeliverySummary FROM qry1"
Then you can add the fields if they aren't there.
On Error Resume Next: db.Execute "ALTER TABLE MyReceivingOnTimeDeliverySummary ADD COLUMN Early NUMBER": Err.Clear: On Error GoTo 0
On Error Resume Next: db.Execute "ALTER TABLE MyReceivingOnTimeDeliverySummary ADD COLUMN Late NUMBER": Err.Clear: On Error GoTo 0
On Error Resume Next: db.Execute "ALTER TABLE MyReceivingOnTimeDeliverySummary ADD COLUMN OnTime NUMBER": Err.Clear: On Error GoTo 0
Finally, fix the nulls to zero.
db.Execute "UPDATE [MyReceivingOnTimeDeliverySummary] SET [Early] = Nz([Early],0)"
db.Execute "UPDATE [MyReceivingOnTimeDeliverySummary] SET [Late] = Nz([Late],0)"
db.Execute "UPDATE [MyReceivingOnTimeDeliverySummary] SET [OnTime] = Nz([OnTime],0)"
Why do it this way? In my experience, SQL is a lot faster than recordsets.
Set the default value to zero for any of the MyReceivingOnTimeDeliverySummary fields which may not be present in the pivot query.
Then loop through the fields in the pivot query recordset and add those fields' values to the matching fields in the other recordset.
Dim fld As DAO.Field
If Not (rs.BOF And rs.EOF) Then
rs.MoveFirst
Do While Not rs.EOF
rs1.AddNew
For Each fld In rs.Fields
rs1.Fields(fld.Name).value = rs.Fields(fld.Name).value
Next
rs1.Update
rs.MoveNext
Loop
End If
Incidentally, you may also find the code operates faster if you substitute dbAppendOnly for dbOpenDynaset here:
OpenRecordset("MyReceivingOnTimeDeliverySummary", dbOpenDynaset)
I'm unsure how much of an impact that change will have. It doesn't change the logic of what you're trying to accomplish. And perhaps any speed impact would be insignificant. But it won't cost you much to find out. :-)

How to compare two access databases to compare database records

How can i compare two MS ACCESS 2007 databases.Both databases contain same tables with same feilds ad structure.i need to compare the record values between two databases to detect any difference in record values.
ACCESS 2007 Database1
serial no. | NAME | ADDRESS
1 smith street 1
2 john street 4
3 alix street 8
ACCESS 2007 Database2
serial no.| NAME | ADDRESS
1 smith street 1
2 jhn stret 4
3 alix street 8
I need a VBA code for ms access that can detect the differece of records,just as the records at serial number two.
First thing you should do is link in one of the tables to the other database, e.g link the Database 2 table into database one (this allows both to be queried together) then you could use this simple example with concatenation to determine if all the fields strung together match based on the serial number:
SELECT T1.*, T2.*
FROM Table1 As T1, Table2 As T2
WHERE T2.[serial no.] = T1.[serial no.]
AND T2.[NAME] & T2.[ADDRESS] <> T1.[NAME] & T1.[ADDRESS]
You could also specify the columns with each of their own condition if you prefer.
NOTE: This is assuming you are only looking for differences where the serial no matches, if you also need to identify records that may appear in one table but not the other then you will need to use an "Un-matched" query, the query designer can help you with this or post back and I can update my answer.
Option Compare Database
Private Sub Command4_Click()
Dim tablename1, tablename2 As String
tablename1 = Text0.Value
tablename2 = Text2.Value
'On Error GoTo Err_cmdValidateGeneralInfo_Click
Dim F As DAO.Field
Dim rs As DAO.Recordset
Dim rs1 As DAO.Recordset
Set curDB = CurrentDb()
'If Me.DateModified = Date Then
'Adds new employees to the TT_GeneralInfo table in the FTEI_PhoneBook.mdb - which is used thru out the AP databases.
' DoCmd.OpenQuery "qryEmpData_TT_General"
strsql = "Select * from " & tablename1
Set rs = curDB.OpenRecordset(strsql)
strsql1 = "Select * from " & tablename2
DoCmd.CopyObject , "Unmatched_records", acTable, tablename1
curDB.Execute "DELETE FROM Unmatched_records"
Set rs1 = curDB.OpenRecordset(strsql1)
Do Until rs.EOF
For Each F In rs.Fields
If rs.Fields(F.Name) <> rs1.Fields(F.Name) Then
'rs.Edit
strsql = "Select * into test from " & tablename1 & " where " & F.Name & " = """ & rs.Fields(F.Name) & """"
DoCmd.RunSQL strsql
If DCount(F.Name, "test") <> 0 Then
GoTo append_unmatch
'appending unmacthed records
append_unmatch:
strsql2 = "insert into Unmatched_records Select * from test"
DoCmd.RunSQL strsql2
'if record doesnt match move to next one
GoTo Nextrecord
End If
' rs.Fields(F.Name) = rs1.Fields(F.Name)
' rs.Update
End If
Next F
Nextrecord:
rs.MoveNext
rs1.MoveNext
Loop
'To check whether tables matched or not
Dim rs2 As DAO.Recordset
strsql3 = "select * from Unmatched_records"
Set rs2 = curDB.OpenRecordset(strsql3)
For Each F In rs2.Fields
If DCount(F.Name, "Unmatched_records") <> 0 Then
MsgBox ("The two tables didnt match. Check table test for unmatching reocrds.")
Else
MsgBox ("Tables match!")
End If
Exit Sub
Next F
rs2.Close
End Sub