I am trying to show all the users that is currently on my Access database. I am using a VBA code that I found online and am trying to modify it to my needs. I am trying to get all the available users and display it on List Box on my form called "ListUsers".
The code is able to output to the debug window but I'm unable to update my list box. I get the following error: "Run-time error '6014': The RowSourceType property must be set to 'Value List' to use this method." I looked on the property window for that list box and couldn't find anything related to RowSourceType. I have tried a few different suggestions online but I am still unable to update the list box, so I wanted to see if anyone here may have some ideas. My code is below, I placed the VBA code on a button click.
Option Compare Database
Option Explicit
Private Sub cmd_Users_Click()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.recordset
Dim i, j As Long
Set cn = CurrentProject.Connection
' The user roster is exposed as a provider-specific schema rowset
' in the Jet 4.0 OLE DB provider. You have to use a GUID to
' reference the schema, as provider-specific schemas are not
' listed in ADO's type library for schema rowsets
Set rs = cn.OpenSchema(adSchemaProviderSpecific, _
, "{947bb102-5d43-11d1-bdbf-00c04fb92675}")
'Output the list of all users in the current database.
Debug.Print rs.Fields(0).Name, "", rs.Fields(1).Name, _
"", rs.Fields(2).Name, rs.Fields(3).Name
While Not rs.EOF
Debug.Print rs.Fields(0), rs.Fields(1), _
rs.Fields(2), rs.Fields(3)
ListUsers.AddItem "'" & rs.Fields(0) & "-" & rs.Fields(1) & "'"
rs.MoveNext
Wend
End Sub
I figured it out... I had to set the RowSourceType on the code. I added the following to the button click event:
Me.ListUsers.RowSourceType = "Value List"
There is also a good post here:
Ms Access AddItem with VBA
Related
I'd like a way to programatically convert Access macros to VBA modules. I know how to do this manually. I was working with some code to do this within the current database and I got it to work. However, I would like to be able to do this outside of the current database. I plan to have this program housed with other utility type programs in the same database. Below is my code. I am getting a message that says, "Microsoft Access cannot find the test1 you referenced in the Object Name arguement. Do you have any suggestions on how to acheive what I want to acheive?
Private Sub Command2_Click()
MsgBox "start here"
Dim strDB As String
Dim appAccess As Access.Application
Dim m As Object
strDB = "C:\Users\me\Desktop\testme.accdb"
Set appAccess = New Access.Application
appAccess.OpenCurrentDatabase strDB
For Each m In appAccess.CurrentProject.AllMacros
Debug.Print m.Name
DoCmd.SelectObject acMacro, m.Name, True
DoCmd.RunCommand acCmdConvertMacrosToVisualBasic
Next
Set appAccess = Nothing
End Sub
DoCmd is a member of the Application object. Ask those commands to work from the new Application object instance you created (appAccess) instead of the Application instance which is running your Command2_Click() procedure.
appAccess.DoCmd.SelectObject acMacro, m.Name, True
appAccess.DoCmd.RunCommand acCmdConvertMacrosToVisualBasic
In other words, basically do the same for DoCmd as you did with appAccess.OpenCurrentDatabase and appAccess.CurrentProject ... you associated them to the specific Application instance.
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 had a form with some VB code that was using Access 2003. Recently we wanted to use the same form as a small front end interface for another database that has a SQL Server backend. However, the file type for this project in Access is .adp and not all of the vb code is working properly. If you could help me fix the bugs in this code:
Private Sub SurveyNameCombo_AfterUpdate()
Dim db_CFC As DAO.Database
Set db_CFC = CurrentDb
Dim rst As DAO.Recordset, query As String, count As Integer
query = "SELECT DISTINCT SurveyID FROM tbl_SurveyMeta WHERE SurveyName = " & Chr(34) & Me.SurveyNameCombo.Value & Chr(34)
Set rst = db_CFC.OpenRecordset(query)
count = rst.RecordCount
If count > 1 Then
Me.SurveyIDCombo.RowSource = query
Else
rst.MoveFirst
Me.SurveyIDCombo.Value = rst.Fields(0).Value
Call SurveyIDCombo_AfterUpdate
End If
End Sub
It is throwing errors in the for the DAO.Database and DAO.Recordset.
Thank you for your help!
The error message "User-defined type not defined" on a line such as this ...
Dim db_CFC As DAO.Database
... means your application doesn't include a reference to the Microsoft DAO Object Library.
Open a code module, then check from the main menu in the VBE editor: Tools->References
Ordinarily the cure would be to place a check mark in the box next to Microsoft DAO Object Library, then click OK. However, your application is an ADP, and I don't know whether DAO can even be used in ADP. You can try. :-)
Sorry I can't tell you more. I quit using ADP a few years ago. Instead I use the MDB format with ODBC links to SQL Server database objects. Perhaps you could consider the same approach if you're unable to get the ADP version working as you need.
I have a form that contains multiple partners that share a "pool". The partners are listed on a subform. After I'm done entering the information, I want a button to run a report for each of the partners with their specific information. But since it's multiple partners and I need one report for each (which I then want to email), I want to use a Loop to go through each of the partners.
EDIT1: Added entire code for review. I do have Option Explicit in and I have compiled it as well.
Private Sub btn_Run_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
strSQL = "Select * FROM Cobind_qryReport WHERE PartPoolName = """ & Me.TopLvlPoolName & """"
Debug.Print "strSQL: " & strSQL
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL)
On Error GoTo Err_PO_Click
If MsgBox("Do you wish to issue the cobind invites?", vbYesNo + vbQuestion, "Confirmation Required") = vbYes Then
rs.MoveFirst
Do While rs.EOF = False
DoCmd.OutputTo acOutputReport, "Cobind_rptMain", acFormatPDF,_
"K:\OB MS Admin\Postage\CoBind Opportunities\Sent Invites\" _
& rs!CatCode & "_" & rs!PartPoolName "Cobind Invite_" & _
Format(Now(), "mmddyy") & ".pdf"
DoCmd.SendObject acSendReport, "Cobind_rptMain", acFormatPDF, ,_
, , " Cobind Invite", "Please find the cobind invite attached._
Response is needed by " & [RSVP] & ". Thank you.", True
rs.MoveNext
Loop
End If
Exit_PO_Click:
MsgBox ("It didn't work")
rs.Close
Set rs = Nothing
Set db = Nothing
Exit Sub
Err_PO_Click:
MsgBox Err.Description
Resume Exit_PO_Click
End Sub
This should allow me to create a report for each record in my query, save it to my server, then open an email to send it out. Right now, it appears that the [PartPoolName] is hanging up the code because I'm getting a "Microsoft Office Access can't find the field "|" referred to in your expression." If I take out the [PartPoolName], it'll create a PDF with four pages (each page showing a partner), where I want to end up with four separate PDFs.
The first thing you should do is add Option Explicit to the Declarations section of your module.
Then, from the Visual Basic editor's main menu, select Debug->Compile [your project name here]
Fix all the problems the compiler complains about. I suspect one of the compiler's first complaints may be triggered by this section of your code:
rs.MoveFirst
Do While Recordset.EOF = False
Do you have two recordset objects open, or one?
After you fix everything the compiler complains about, try your revised code.
If you get runtime errors, show us the exact error message and which code line is highlighted.
If the part of your code you haven't shown us includes an error hander, you can disable that error handler like so:
'On Error GoTo Err_PO_Click
Error handlers are great for production to shield users from errors. However, during development you really need to be able to identify which code line causes the error.
Alternatively, you can leave your error handler active and select Tools->Options from the editor's main menu. In the Options dialog, select the General tab, then select the "Break on All Errors" radio button and click OK. You can switch that option back to "Break on Unhandled Errors" after you finish your testing.
Update: You wrote: Right now, it appears that the [PartPoolName] is hanging up the code because I'm getting a "Microsoft Office Access can't find the field "|" referred to in your expression."
What is [PartPoolName]? If it's a field in the recordset, you can reference its value as rs!PartPoolName If it's something else, perhaps a global variable, give us more information about it.
Update2: Whenever your current code completes without error, you will hit this:
Exit_PO_Click:
MsgBox ("It didn't work")
Can that be right?
Update3: This OutputTo statement is your issue now, right?
DoCmd.OutputTo acOutputReport, "Cobind_rptMain", acFormatPDF,_
"K:\OB MS Admin\Postage\CoBind Opportunities\Sent Invites\" & _
"Cobind Invite_" & Format(Now(), "mmddyy") & ".pdf"
Cobind_rptMain is a report. It has a RowSource for its data. You're calling OutputTo with that report 4 times (once for each of the 4 rows in the recordset). Yet you expect 4 different versions of that report ... a separate report for each PartPoolName value?
To finish off the fine work by HansUp visit a page on how to print a report for a single record and how to generate reports to attach to emails. See the Emailing reports as attachments from Microsoft Access page.
HI,
I am trying to write a query in vba and to save its result in a report.
I am a beginner. this is what i have tried
can somebody correct me
Dim cn As New ADODB.Connection, rs As New ADODB.Recordset
Dim sql As String
Set cn = CurrentProject.Connection
sql = "Select * from table1 where empno is 0"
rs.Open sql, cn
While Not rs.EOF
' here i think i should save the result in a report but i am not sure how
rs.MoveNext
Wend
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
Also how do i change this query to run this on all tables in a database
IF you are wanting to create a report using MS Access's report generator, you will have to use a Query Object (there might be a way to trick MS Access into running it off of your record set, but it's probably not worth your effort).
You can create the Query Object on the "Database" window. Click the Query button in the objects list, and then click on New. In the resulting editor you can create the query graphically or if you prefer with SQL. Save the query and give it a meaning full name.
Similarly the report can be created on the "Database" window. Click on the Report button and then on New. In the resulting wizard, you'll link the report to the query you just created.
Update: As D.W. Fenton said, you can embed the query right within the Report Object without creating a separate Query Object. My preference is to create one anyway.
The problem with this method is you would have to create a separate query and report for each table.
IF you just want to dump the result out to a text file (to read/print later), then you can do it using recordsets like you are in your VBA code. It will look something like this
'...
dim strFoo as string
dim strBar as string
'...
if not rs.bof then
rd.MoveFirst
end if
While Not rs.EOF
strFoo = rs("foo") 'copy the value in the field
'named "foo" into strFoo.
strBar = rs("bar")
'... etc. for all fields you want
'
'write out the values to a text file
'(I'll leave this an exercise for the reader)
'
rs.MoveNext
Wend
'...
Parsing all of the tables can be done in a loop something like this:
dim strTableName as string
dim db As Database
'...
Set db = CurrentDb
db.TableDefs.Refresh
For Each myTable In db.TableDefs
If Len(myTable.Connect) > 0 Then
strTableName = myTable.Name
'...
'Do something with the table
'...
End If
Next
set db = nothing
=======================UPDATE=======================
It is possible to run an MS-Access Report from a record set. To repease what I said to tksy's question
From Access Web you can use the "name" property of a recordset. You resulting code would look something like this:
In the report
Private Sub Report_Open(Cancel As Integer)
Me.RecordSource = gMyRecordSet.Name
End Sub
In the calling object (module, form, etc.)
Public gMyRecordSet As Recordset
'...
Public Sub callMyReport()
'...
Set gMyRecordSet = CurrentDb.OpenRecordset("Select * " & _
"from foo " & _
"where bar='yaddah'")
DoCmd.OpenReport "myReport", acViewPreview
'...
gMyRecordSet.Close
Set gMyRecordSet = Nothing
'...
End Sub
Q.E.D.
Normally you would design the report based on a data source. Then after your report is done and working properly you use VBA to display or save the report.
To run this for each table in the database, I'd suggest writing a function that looped through CurrentData.AllTables(i) and then called your function above in each iteration
Hope this helps
If you want to simply view the results, you can create a query. For example, here is some rough, mostly untested VBA:
Sub ViewMySQL
Dim strSQL as String
Dim strName As String
'Note that this is not sensible in that you
'will end up with as many queries open as there are tables
For Each tdf In CurrentDB.TableDefs
If Left(tdf.Name,4)<>"Msys" Then
strName = "tmp" & tdf.Name
strSQL = "Select * from [" & tdf.Name & "] where empno = 0"
UpdateQuery strName, strSQL
DoCmd.OpenQuery strName, acViewNormal
End If
Next
End Sub
Function UpdateQuery(QueryName, SQL)
If IsNull(DLookup("Name", "MsysObjects", "Name='" & QueryName & "'")) Then
CurrentDb.CreateQueryDef QueryName, SQL
Else
CurrentDb.QueryDefs(QueryName).SQL = SQL
End If
UpdateQuery = True
End Function
You may also be interested in MDB Doc, an add-in for Microsoft Access 97-2003 that allows you to document objects/properties within an Access database to an HTML file.
-- http://mdbdoc.sourceforge.net/
It's not entirely clear to me what you want to do. If you want to view the results of SQL statement, you'd create a form and set its recordsource to "Select * from table1 where empno is 0". Then you could view the results one record at a time.
If that's not what you want, then I'm afraid I just don't have enough information to answer your question.
From what you have said so far, I don't see any reason why you need VBA or a report, since you just want to view the data. A report is for printing, a form is for viewing and editing. A report is page-oriented and not that easy to navigate, while a form is record-oriented, and allows you to edit the data (if you want to).
More information about what you want to accomplish will help us give you better answers.
Had the same question. just use the clipboard!
select the query results by click/dragging over all field names shown
press ctrl-c to copy to windows clipboard
open a blank document in word and click inside it
press ctrl-v to paste from clipboard.