Order sub to click userform commandbutton from sub - arrays

I am writing here because I cannot seem to find the answer on the internet.
Context of my sub and userform : I have several pivottables in the same sheet in a workbook.
These pivottables may have random names given by other users changing them unintentionally or not knowing the names are essential to the rest of the code. This is why i created a userform which has on one side the ideal name of each pivottable, and on the other side, comboboxes with the current names, like so:
pivottable dealing with x // combobox with all current names (user has to choose which one of the current names corresponds to the this pivottable)
pivottable dealing with y // combobox with all current names (user has to choose which one of the current names corresponds to the this pivottable)
pivottable dealing with z // combobox with all current names (user has to choose which one of the current names corresponds to the this pivottable)
and finally a button "VALIDATE"
here is a screenshot of my userform : enter image description here
WHAT I AM TRYING TO DO :
since the user has to inform the userform which pvttable corresponds to which title, i have written :
userform1.show vbmodeless
so that the user can go check the current titles of the pivottables and associate them with the correct one. Because I have put the vbModeless, the sub does not wait for the user to validate and thus fills the title with nothing or blank as nothing from the combbox has been chosen since the user hasn't had the time yet. Therefore, I want to signal that once and only once i clicked on "valider", then the sub changes the current titles to the ideal titles (can only do in the sub and not in the userform because i actually use an array that is subject to changes in the ideal names, and I can't put it in the userform because it is defined above in the sub, ican't pass it over to the userform). I am triyng to use something like :
if userform1.commandbutton1.click = true then
'and put pvtnames = userform1.combobox1.value
(but i am alright with the pvtname part). IS THERE A WAY TO CODE THE BUTTON.CLICK PART ? thank you ever so much for your help, i am sorry for the long message

Related

Connect multiple tables in Access

I want to connect multiple tables in Access. I have a main table and then multiple smaller tables that I would like to connect. Each row in the main table belongs to one entire sub-table. I would like to have small + appear next to each row in the main table and showing the sub-tables upon clicking on the +.
I tried this via relationships but it only works for the first row (perfectly) but not for any other rows. When clicking on the other rows, they are empty and no sub-table is opening up.
Any ideas?
Per the comments if you must do this here is an example:
example main table and sub tables
example form created from the main table using the create form wizard and selecting tabular to get a better looking starting form:
note I added an unbound button to the details section and that button gets replicated for each row of data. I will show two ways of setting up the button to open the correct form.
put the form in design mode open the button's properties and open the onclick event. you can do this with the macro language but I show the code:
Private Sub openButton_Click()
'each button the detail section creates has access to the data or controls in the buttons row
DoCmd.OpenTable Me.subTableName 'if form use .OpenForm
'DoCmd.Close acForm, "mainForm" 'if want to close main form
'OpenTable (MainID)
End Sub
if the logic behind opening the form gets complicated I suggest abstracting the logic to a function. here use OpenTable instead and add the Public OpenTable function inside a code module.
Public Function OpenTable(tableID As Long) As Boolean 'function allows the option checking the return value to test if OpenTable worked
Select Case tableID
Case 1
DoCmd.OpenTable "subTable1"
Case 2
DoCmd.OpenTable "subTable2"
Case 3
DoCmd.OpenTable "subTable3"
End Select
OpenTable = True
End Function
Note: you could expand the form's header and show the mainTable as a subform in that header. Then you could add a button next to each row in that subform but outside the subform. The approach I show is easier to maintain.

MS Access Foreign Key Record Fill Too Fast

I have a problem with one of my forms in my MS Access database, and strangely it's the only form that has this problem.
The form has a typical Master/Detail structure, with the subform tied to a table. The subform record source includes a foreign key that pulls information from another table and populates the rest of the fields based on the key value. This foreign key is a Material number that defines a specific object in an inventory, and the other fields in the subform show details of this object.
Example from Signs table:
Material number: 116063175
StorageBin: A116
Material Description: Stop Sign
Dimensions: 48x48
All of this information is contained in the same table, but the form is for a table that is used to fill in what signs are on a particular road (stops, speed limits, etc.)
On all my other forms, when I type in the material number and shift focus anywhere else, the rest of the forms will fill in automatically. This process works here too, but for some reason Access wants to try to fill in the rest of the field data before I have finished typing the material number. I'll type "1" and access will throw an error that it cannot find a matching record in the Signs table in the foreign key's table. After rejecting the error twice, the data entry can resume as normal, which is also strange.
I hope I've been clear enough, this is my first time asking a question here.
Thanks in advance!
Edit: Tried re-building the form, same issue. Built another form similar but without my multiple comboboxes, didn't have the issue! Could this be due to underlying requery code in the Afterupdate event of my comboboxes? I have a cascading combobox setup on the form, could data entry be triggering a requery?
Edit2: for the time being, a fix that I am using is to make the material number and quantity (the two important fields for this form) into text boxes outside the subform, that the user can edit then place in the subform with a button click, which is coded as so:
Private Sub Command1_Click()
If Me!PrimaryRoadInventorySubform.Form.Dirty Then
Me!PrimaryRoadInventorySubform.Form.Dirty = False
End If
Me!PrimaryRoadInventorySubform.SetFocus
DoCmd.GoToRecord , , acNewRec
Me!PrimaryRoadInventorySubform.Form!MaterialNumber = MaterialNumtxt
Me!PrimaryRoadInventorySubform.Form!Quantity = Quantitytxt
End Sub

Unable to pass value from one form to another - Ms access

I have a multiple VBA forms, the first form takes user's name from a combo box and saves it in a global variable, code is below :
Option Compare Database
Public emplID_global
Private Sub OKLogin_Click()
If Not IsNull(Me.Combo_emplID) Then
emplID_global = Me.Combo_emplID.Column(1)
DoCmd.Close
DoCmd.OpenForm "NavFrm", acNormal
End If
End Sub
Now in my other form I have a combo box in which I want to auto-populate the valueof that variable, on load of form, which i saved using previous form, below is the code :
Private Sub Form_Load()
Me.AdvName = emplID_global
Me.DataForm.Form.Recordset.MoveLast
End Sub
but it is not working, It is not doing anything. I want to use this kind of code in all the forms.
Can someone please suggest what is the mistake in my code, i am fairly new to VBA. Thanks in advance :)
Add a field to your underlying table for the owner of that particular record. (I just called it Owner.)
Add the following code to your form:
Private Sub Form_BeforeInsert(Cancel As Integer)
Owner = Environ("username")
End Sub
Private Sub Form_Current()
Dim editable As Boolean
if nz(Owner,"")="" then
editable=true
else
editable = (Environ("username") = Owner)
End If
Form.AllowDeletions = editable
Form.AllowEdits = editable
End Sub
This is a fairly generic solution that does the job. Environ("username") returns the user's windows username. This is not necessarily all that secure. A person could go to the command prompt and edit the username environment variable so that they appear to be another person. This will definitely not keep out the NSA or anyone else with a little computer knowledge and bad intentions. But it will keep the honest people honest.
Explanation:
The BeforeInsert runs as a new record is being saved. In this case, it sets the record's Owner field to the user's Windows username.
The OnCurrent portion runs every time a new record is displayed. The code will check to see if the current Windows username matches the username stored in the record's Owner field and set the forms AllowEdits and AllowDeletions flags accordingly. Also, if the Owner field is null (as in the case of a new record), editable will be set to true. If you wanted to really emphasize the fact that the user shouldn't be changing things, you could also enable/disable the individual text boxes...
TextBox1.Enabled=editable
ComboBox2.Enabled=editable
... etc.
Simple solution. Keeps honest people from overwriting each others' work. I use this approach a lot.

VB2010 reading menu items in tool strip sub menu

SQL Server/VB2010 newbie. Fighting the learning curve on two fronts.
I am creating a UI in VB2010 to a SQL Server database that will allow users to edit tables in the database. Since the tables in the database may change (new ones added, or obsolete ones deleted) as the project develops, the table names are dynamically added to the sub menu, as shown in the screen cap below:
Then I use the AddHandler function to run the click event sub. That works fine, but what I need to do is grab the actual text of the submenu item ("VehicleList", "Maintenance", etc.) to use in the SQL SELECT string to open the selected table in the database, like so:
"SELECT * from [selected_menu_item] WHERE yada, yada"
I've scoured the internet looking for this, but if it's there, I can't find it. Tried many ways, but I either get the top menu item ("Table") or the last item on the list, or sometimes just a blank line.
Preferable would be to get the actual names, but even if there was an index value, I could use that to reference an array of the table names.
Can anyone help?
Thanks!
The answer is to use the "ByVal e As ToolStripItemClickedArgs" argument in the handler, like this:
Private Sub MenuItem_click(ByVal sender As System.Object, ByVal e As ToolStripItemClickedEventArgs)
Debug.WriteLine(e.ClickedItem.Text)
End Sub
Found this at http://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripitemclickedeventargs.clickeditem.aspx
It works exactly as I need it to!

Counting instances of a parameter value on an access form

I'd like to display, in the form footer of a Microsoft Access form, a count of a particular value of a field ("Category") I have tried using
=Sum(IIf([Category]="S",1,0))
as the control source for the text control in the footer, but this fails. I cannot figure out why I cannot perform this calculation on this control/field combination. I suspect it has to do with "Category" not being the control source for any control, even though it's available in the second column of my combo box.
I have performed the count on the "Appliance" field instead, and the sum function works correctly, So I'm pretty sure my general syntax and references aren't completely broken. Both underlying values are text fields.
I'd love some help with how I can get to the second parameter of the query with the Sum function?
Specifics:
ComboBox
Name is "lstAppliance". Bound Column: 1 , Row source :
SELECT qryApplianceDetails.Appliance, qryApplianceDetails.Category FROM qryApplianceDetails;
Text Box
Name is "txtCategory" , Control Source:
=Appliance.Column(1)
In case this isn't clear enough, what I'd like to see looks something like this:
Form header:
Appliance , Category
Form detail
Truck , S
Truck , L
Car , S
Bike , M
House, L
Planet , S
Form footer
Number of "S" things: 3
With this source in the footer:
=Sum(IIf([Appliance]="Truck",1,0))
Displays "2", as you would expect, but:
=Sum(IIf([Category]="S",1,0))
Displays "#error", instead of "3" as I'd expected.
I would try something simpler, but not sure if this will be too simple for what you need.
Use this expression as the control source for txtCategory:
=DCount("*", "qryApplianceDetails", "Category='S'")
Then in the form's On Current and After Update events, add this:
Me.txtCategory.Requery
In regard to the issue of using a field in the form's recordsource in an expression (or in VBA code), since A2000, things have become more difficult. It's not reliable if the field you're using has not been used as the ControlSource of a control on your form. The workaround is to create an invisible control with the field as its ControlSource.
Another way of working around that problem would be to create a control with this ControlSource:
=Val(IIf([Category]="S", 1, 0))
...then Sum() on that control.
I don't like the idea of using a DCount() as it requires a hit on the database for data that's already in the form. Secondly, if this is in a subform, the DCount() would need to be filtered not just on the Category value but also on whatever the link field is between the subform and its parent. It just gets so fussy that I'd say it's better to go with something that can be derived from the recordset already loaded in the form.

Resources