Adding multiple textboxes to a form in ms-access? - vba

I would like to have a line on an Access user-form. Call it Item #1. I would like Item #1 to be a text box where the user can enter any type of information. So for example, say the user entered "Tutoring" and then next to this was an additional Textbox that allowed the user to enter the hours spent tutoring and the date in which the hours were logged.
What I would like is to have a button to allow the user to add a second line (or set of textboxes) when needed, or a third line, etc. Is this something that can be set up on the Access form? Does this need to be coded in VBA? Just looking for some tips to provide me some direction on the best approach.

"If the data should not be stored in a table, it' a bit more complicated. "
You would have to make the text boxes not visible when the form loads, and then make each text box visible on the After Update event of the previous box.

Related

MS Access one form to select table values and use to populate multiple fields on other form?

I have a table called GL_Account and IM_Productline
The table IM_Productline has various fields that need to be populated with a value from the field GL_Account.AccountKey (i.e. IM_ProductLine.InventoryAcctkey and IM_ProductLine.CostOfGoodsSoldAcctKey)
To populate the IM_ProductLine table I made a form "Product Line Maintenance" with all the fields. To populate the field IM_ProductLine.InventoryAcctkey I put a (magnifying glass) button behind the field with the following code:
Private Sub CMD_Select_GL_Account_Click()
Me.Refresh
If IsNull(Select_ProductType) Then
'do nothing
Else
Forms![Product Line Maintenance].InventoryAcctkey = Me.SelectGLAccountKey.Column(0)
Forms![Product Line Maintenance].Refresh
End If
DoCmd.Close
End Sub
So the button opens a form Called "Select GL Account" with a combo box that enable to SELECT GL_Account.AccountKey, GL_Account.Account, GL_Account.AccountDesc
FROM GL_Account; and when the OK button is clicked it writes the value from GL_Account.AccountKey to IM_ProductLine.InventoryAcctkey, closes the form "Select GL Account" and then refreshes the form "Product Line Maintenance" so the account number and description become visible for the user.
This all work fine but here's my question:
Now rather than creating a new form for every account field I need to populate (i.e. "Select Inventory GL Account" select "Cost Of Goods Sold GL Account" etc) I'd prefer to use the form "Select GL Account" to select and populate the 11 different account fields. So behind each xxxAcctkeyfield on form "Product Line Maintenance" is a (magnifying glass) button that when clicked pulls up the form "Select GL Account" and when "OK" is clicked it writes the selected AccountKey to the correct field on form "Product Line Maintenance"?
I'd greatly appreciate anyone's efforts to understand what I am trying to explain and point me in the right direction.
Ok, there is the issue that all 11 fields should not require to be "copied" since you have a relational database (you would ONLY store the row PK ID of that selection in the current report. (a so called FK (foreign key) value). That way, say you want to change the choice? Well then you could pop up that form - search + select the one record with all that information, and then upon return ONLY store the one value.
So, I would give some thoughts to the above - you want to leverage the relational database features. And as a result, you don't need to "copy" all that data. This is not much different then say creating a invoice. I can create the new invoice, but all of the address information, and the customer that this ONE invoice belongs to? Well, that is one column with a FK value that points to the customer. Once I select that one customer, then display of the customer name + address can be say a sub form or some such - but no need exists to "copy" that information. It would also means with near zero code, you could move a invoice between customers!!! - (just change the one fk column with to the new/different customer ID (PK) value.
Now, back to the question at a hand?
You can certainly pop up a form, let the user select, enter, pick and do whatever. And THEN you can have the calling code grab + pick out the values from that form.
The way you do this? It involves a not too wide known trick.
The code that calls the form can simply open that form as a dialog form. This will HALT the calling code, the user does whatever, and when done the calling code will THEN continue. Not only does the calling code continue, but it can get/grab/pull/take any values from that pop up form WIHOUT having to use global vars.
The approach is thus thus:
dim strF as string
strF = "frmPopAskInfo"
docmd.OpenForm strF,,,,,,acDialog
' above code waits for user input
if application.AllForms(strF).IsLoaded = true then
' user did not cancel, get values from form
me!AccountNo = forms(strf)!AccountNumber
etc. etc. etc.
docmd.Close acForm,strF
end if
Now the only other issue? Well, the "ok" button on the popup for DOES NOT close the form, what it does is set visible = False. This will kick the form out of dialog mode.
me.Visible = False
So, if the user hits the cancel buttton (close form) or hits the X upprer right (close form), then the form will NOT be loaded when your calling code continues. But, if they hit OK button, then you don't close the form, but ONLY set visbile = false.
This allows the calling code to continue, you are free to get/grab/take values from that form, and then once done, you close the form.
So a form close in that popup = user canceled the form.
So, a popup form, and even a modal form? They do NOT halt the VBA calling code, but a acDialog form does!
You can thus place 2 or 5 little buttons that pops up this form, the user can pick/choose/select/enter values. When they hit ok, your calling code continues, and you are free to pull values from that form. So while all 3-4 buttons might pop up that form, each individual button launch of the form can have code that follows and updates the given control the pop button was placed beside.

MSAccess VBA: Pass values from a subform to a seperate form

I have a form frmDetail that contains several locked fields I want populated only when another form has been filled out, in the name of having some kind of standardization in my data. This other form frmSignOut is used to enter in a date and location that will populate the fields on frmDetail. frmSignOut also contains a subform subULookup that looks up users from a different table using an identifier number. The resulting last name, first name and phone # should also be passed to frmDetail. I also hope to combine first and last name somehow into a Last,First format.
My approach so far has been to open frmSignOut modally with acDialog and I inserted Visible=False into the On_Click event on frmSignOut. Then I try to reference my subform fields and set them to the desired fields on frmDetail. I finish by refreshing and then closing the dialog form.
Private Sub CmdSignOut_Click()
DoCmd.OpenForm("frmSignOut"),,,,,acDialog
If CurrentProject.AllForms("frmSignOut").isLoaded=True Then
Set Forms!frmSignOut!SubULookup.PhoneNbrTxt=Me.ContactNbrTxt
DoCmd.Close (acForm), ("frmSignOut")
Me.Refresh
End If
End Sub
I have only been able to get this far, trying to pull the first field PhoneNbrTxt. I can get frmSignOut to open, I put in data and when I click my 'close' command button I get run-time error 438: Object doesn't support this property or method.
The line highlighted is where I try to reference my subform field. I also have a 'Cancel' button added to frmSignOut that just closes the form, I have no errors there.
Again I'm completely new to Access without much prior experience in anything related, I'd appreciate any knowledge you guys can throw at me.
EDIT: I've been able to successfully pull the value to Me.ContactNbrTxt by adjusting my code to the below.
Me.ContactNbrTxt = Forms!FrmSignOut!SubULookup.Form!PhoneNbrTxt
It looks like the missing part was the Form! right before the control name, along with formatting this correctly and dropping Set.
Im still trying to work out how to combine first and last name before also pulling those to frmDetail, if anyone can help there.

Excel VBA Userform - How do I add a value to a combo box from a list in the userform?

Is there a way to do the following:?
I would like a manual text box that when filled in and the user clicks "Add" and it adds the value to the combo box. However, I will also have this list stored somewhere so that the next time the user loads the form they can select "Previously Used" items from a list and these will then also be added to the combo box.
I will be adding a button to "Add all" of the previous items but it must still have the option to add items manually each time.
Even more useful would be to have an option to check items in and out of the combo box as well as the manually text input option.
I tried to add an image I found to better explain this but I need 10 rep points. Therefore, I hope this makes sense but please feel free to comment for more details and a better explanation if needed.
Link to an example of what I am thinking of but without the manual addition field:
http://kb.blackboard.com/download/attachments/14057766/bbui_multi_select.gif?version=1&modificationDate=1202823953747
Use this
combobox1.additem txtValue.Text
Sheets("SheetName").Cells(lastRow+1,col).value=txtValue.Text
Also add below code in Form_activate
For i=1 to lastrow
combobox1.additem Sheets("SheetName").Cells(i,col).value
next i

Gray out a form row's (detail's) button conditionally with VBA code

I have a standard form in MS-Access which lists a bunch of orders, and each row contains order no, customer, etc fields + a button to view notes and attached document files.
On request from our customer we should gray out the button btnAnm (or check or uncheck a checkbox) depending on a calculation from two queries to two other tables (a SELECT COUNT WHERE and a check if a text field is empty).
I've tried btnAnm_BeforeUpdate(...) and btnAnm_BeforeRender(...) and put breakpoints in the subs, but none of them trigger. The same if I use the control Ordernr instead of btnAnm.
I'd like a function in the Detail VBA code to be triggered for each "Me." (row) so to speak, and set the row's control's properties in that sub.
What do I do? I've looked at the help file and searched here.
*Edit: So I want to do something that "isn't made to work that way"? Ie. events are not triggered in Details.
As an alternative, could I base the value of a checkbox on each line on a query based on the 'Ordernr' field of the current row and the result of a SELECT COUNT from another table and empty field check?
Do I do this in the query the list is based on, or can I bind the extra checkbox field to a query?
A description of how to do this (combine a COUNT and a WHERE "not empty" to yes/no checkbox value) would be perfectly acceptable, I think! :)*
You cannot do much with an unbound control in a continuous form, anything you do will only apply to the current record. You can use a bound control with a click event so that it acts like a button.
Presumably the related documents have a reference to the order number that appears on your form, which means that you can create a control, let us call it CountOrders, with a ControlSource like so:
=DCount("OrderID","QueryName","OrderID=" & [OrderID])
The control can be hidden, or you can set it up to return true or False for use with a textbox, you can also use it for Conditional Formatting, but sadly, not for command buttons.
Expression Is [CountOrders]>0
You can also hide the contents and add a click event so that is acts in place of the command button. Conditional Formatting will allow you to enable or disable a textbox.
As I understand your question, you have a continuous form with as command button that appears on each row - and you'd like to enable/disable the button conditionally depending on the contents of the row.
Unfortunately you can't do that. It seems that you can't reference the individual command buttons separately.
Having wanted to do something similar in the past I came up with two alternate ways of setting up my interface.
Put a trap into the onClick code for the Button. Which is icky, because it is counter intuitive to the user. But it gets you that functionality now.
Move the command button (and editable fields) up into the form header, and make the rows read only. Your users then interact with the record only in the header, and select the record they want work with in the list below. As I recall this is known a Master-Detail interface.

Access 2007: Filtering a report's results using a drop-down box

My question is twofold.
I have around twenty assorted tables in a database. The table layouts are diverse; the one common thread is that all of them have a 'County' field.
I need to set up a series of reports which allow a user to select a county from a drop-down box, triggering the report to run and return only records attached to that particular county.
This is doable at the datasheet level using a filter-by-form, but that's pretty clunky and I have several tables/queries which will need this same county filter.
I may be halfway there with the following:
Create an unbound form.
Add a combo box.
Set the Row Source of the combo box to include the County field.
Set its Bound column to 1.
Set its Column Count property to 2.
Set the Column Width property to 0";1"
Name the Combo Box 'ChooseCounty'.
Add a Command Button to the form.
Code the button's click event as follows:
(Note: To write the code, in Form Design View select the command button. Display the button's property sheet.
Click on the Event tab.
On the On Click line, write:
[Event Procedure]
Click on the little button with the 3 dots that appears on that line.
When the code window opens, the cursor will be flashing between two already existing lines of code.
Between those lines, write the following code.)
Me.Visible = False
Close the Code window.
Name this form 'ChooseCounty'.
In the Query that is the Report's Record Source [County] field
criteria line, write:
forms!ChooseCounty!ChooseCounty
Next, code the Report's Open event:
(Using the same method as described above)
DoCmd.OpenForm "ChooseCounty", , , , , acDialog
Code the report's Close event:
DoCmd.Close acForm, "ChooseCounty"
When ready to run the report, open the report.
The form will open and wait for the selection of the Company.
Click the command button and then report will run.
When the report closes, it will close the form.
I can persuade the report to trigger the form, but only once - I can't seem to figure out where precisely the 'forms!ChooseCounty!ChooseCounty' needs to go. Perhaps someone can clarify or offer a more elegant way to do this?
I need to set up a large meta-report containing sub-reports on all of the tables - and, using the same drop-down 'choose a county' form, I need to have that choice cascade down through all the subreports. I don't have the faintest idea how to go about this. Suggestions welcome!
~ T
You seem to be asking two questions, the last of which is clear to me, but the first is not. The second one is in regard to how to cascade the filter to the subforms. You can do this in one of two ways:
put the form control reference as criterion in the recordsource of each subreport, OR
create a non-visible control on the report that has as it's controlsource "=Forms!ChooseCounty!ChooseCounty". Name that control "CountyFilter". Then, add CountyFilter to the link properties. If, for instance, you are linking the subreports on ID, you'd have:
LinkMaster: ID;CountyFilter
LinkChild: ID;County
(assuming, of course, that ID is your link field for the child reports, and that "County" is the name of the field in the child subreport).
Now, I'm wondering why you would have the County data not just in the parent record but in the child records -- that makes no sense. If you do have it, then the solution above will work.
If you don't, then I don't understand the question, as the whole idea behind subreports is that they are filtered by the parent record, so if the parent record is a person, and you filter by COUNTY, you're only going to get the child records in the subreport for that person, which by definition are already filtered by COUNTY because the parent has been filtered.
As to the earlier question, you write:
I can persuade the report to trigger
the form, but only once - I can't seem
to figure out where precisely the
'forms!ChooseCounty!ChooseCounty'
needs to go
You have two choices:
hardwire the recordsource of the report to use the form control reference, so the WHERE clause of your report would be "WHERE County=Forms!ChooseCounty!ChooseCounty" (and you should set this as a parameter of type text to insure that it gets processed correctly).
the better meethod is to set the recordsource in the report's OnOpen event.
After you open the form as a dialog, you'd have something like this:
Me.Recordsource = "SELECT * FROM MyTable WHERE County='" _
& Forms!ChooseCounty!ChooseCounty & "'"
And immediately after that line, you can close the form, since it's not needed any longer.
You will likely want an OnNoData event for the case where no records are returned. This is usually something simple like:
MsgBox "No records found!"
DoCmd.Close acReport, Me.Name
I hope this answers your questions, but if not, I'm happy to offer more explanation.