MS Access - open a form taking a field value from a previous form - database

I have a form in an MS Access database which lists all the landowners consulted with for a new electricity line. At the end of each row is a button which opens another form, showing the details of all consultation, offers made etc.
I am trying to use vb in MS Access to take the contactID and automatically put it in a field in the details form, so that landowner's consultation details will pop up automatically. I am not a vb programmer at all (I have a comp sci degree mostly in Java and I'm currently working as a GIS analyst but it's a small company so I've been asked to get an Access database working).
I want to say
[detailsForm]![contactID] = [landownerlist]![ID]
in a way that vb and access will be happy with. Then I can see if I'm on the right track and if it will actually work! What I have above does not actually work. It won't compile.
From Kaliana

If you wish to open a form to a new record and to set the ID there, you can use Openargs, an argument of Openform:
DoCmd.OpenForm "FormName",,,,acFormAdd,,Me.ID
The opened form would also need some code:
If Me.Openargs<>vbNullstring Then
Me.Id = Me.Openargs
End If
It is also possible to find:
Forms!LandownersList.Recordset.FindFirst "ID=" & Me.ID
or fill in a value:
Forms!LandownersList!Id = Me.ID
on the form being opened from the calling form.

You may want to look into the code that is behind these buttons. If you are using a docmd.openform you can set the 4th Setting to a where clause on openning the next form.
DoCmd.OpenForm "OpenFormName", acNormal, , "[contactID] = " _
& [detailsForm]![contactID] , acFormEdit, acWindowNormal
This assumes contact ID is numeric and doesn't require any quotes.

Using open args is the generally accepted solution, as alluded to by others. This just falls under the category of "For you edification":) One of the problems with using open args is that unless you are careful with your comments it's easy to forget what they were supposed to mean. Were you passing more than one? Which is which? How did I do it here? How did I do it there etc. For my own money, I standardized to this (below) so I can always pass more than one argument without fear, and when I review my code a year from now, I can still see what's what without a huge hassle:
Option Explicit
'Example use: DoCmd.OpenForm "Example", OpenArgs:="Some Filter|True"
Public Enum eForm1Args
eFilter = 0
eIsSpecial = 1
End Enum
Private m_strArgs() As String
Public Property Get Args(ByVal eForm1Args As eForm1Args) As String
Args = m_strArgs(eForm1Args)
End Property
Private Sub Form_Open(Cancel As Integer)
m_strArgs = Split(Nz(Me.OpenArgs, vbNullString), "|")
If LenB(Me.Args(eFilter)) Then Me.Filter = Me.Args(eFilter)
End Sub
Private Sub Command1_Click()
If LCase$(Me.Args(eIsSpecial)) = "true" Then
'Do something special
End If
End Sub

As previously posted OpenArgs is great for this. One trick I have learned is that it is easy to pass in multiple parameters if required as a delimited string (comma for example), the target form can then access these values using the Split() function thus:
StringArrayVariable()= Split(me.OpenArgs,",")
Me.textbox= StringArrayVariable(0)
Me.textbox1= StringArrayVariable(1)
etc.
This is air code so check out the helpfile for Split().
It is also possible to pass objects in OpenArgs as well, it requires some manual memory pointer manipulation and I don't have the code to hand but I'm sure a Google search will find some examples. This technique can cause some random crashes though. Be Warned!

Related

Search button for a database in vb.net for listview

The code below is not searching, keeps showing error. It is supposed to search for records using a number.
Private Sub btn_search_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_search.Click
Me.Sales_fileBindingSource.Filter = "Receipt Number LIKE '" & "%'" & txt_search.Text & "%'"
End Sub
The error being shown is: Syntax error: Missing operand after 'Number' operator.
Click here to see error screenshot
It would make it easier to see what's going on if the code used an interpolated string, so it might end up like:
Me.Sales_fileBindingSource.Filter = $"[Receipt Number] LIKE '%{txt_search.Text}%'"
It is necessary to put the column name in square brackets as it has a space in it - there are examples of the syntax at DataView RowFilter Syntax [C#] (the syntax for the filter is independent of the language).
If you are using an older version of Visual Basic, before interpolated strings were introduced (the year 2015), you'll need something like:
Me.Sales_fileBindingSource.Filter = String.Format("[Receipt Number] LIKE '%{0}%'", txt_search.Text)
which, while a bit longer, still makes it easier to see what is happening than using lots of " & x & "'-type code.
Finally got it! All i had to do was use an under score to join the two words Receipt and Number to one like this "Receipt_Number" Also made other changes like using String.Format. Check code below.
Me.Sales_fileBindingSource.Filter = String.Format("(Convert(Receipt_Number, 'System.String') LIKE '%{0}%')", txt_search.Text)

RPS, windows Form & Revit API (Python)

I've been trying to build a form to create and delete Revit print Sets.
I've 2 main issues:
1) I'm able to create a print set but I cannot access its content unless I restart the Form. I get the errors below (depending if I'm defining the view_set variable or not)
List_object_has_no_attribute_Views
Local_variable_referenced_before_assignment
This is the code of the function to display the sheets of the selected Print Set
def DisplaySheetsInSet (self, sender, args):
self.curItem = CurrentSetsListBox.SelectedItem
PrintSetForm_Load
try:
view_set=[]
for i in PrintSetForm.ViewSets:
if i.Name == str(self.curItem):
view_set = i
else:
continue
Sheets=[sheet.Name for sheet in view_set.Views]
SheetsLb.BeginUpdate()
SheetsLb.Items.Clear()
for sheet in Sheets:
SheetsLb.Items.Add(sheet)
SheetsLb.EndUpdate()
except Exception as e:
popup (str(e)
2) I'm able to delete print sets once. If I try do delete another one I get the following error and I need to restart the form ( code for the function that deletes the print sets shown below)
The_referenced_object_is_not_valid
def DelPrintSet(self, sender, args):
self.curItem = CurrentSetsListBox.SelectedItems
t = Transaction (doc, 'Delete printset')
t.Start()
for viewset in PrintSetForm.ViewSets:
if viewset.Name in [str(item) for item in self.curItem]:
doc.Delete(viewset.Id)
doc.Regenerate()
else:
continue
self.Refresh()
UpdateSetNames(CurrentSetsListBox)
t.Commit()
I've tried to build a function to restart/refresh the Form but it doesn't work (code below):
global PrintSetForm_Load
def PrintSetForm_Load(self, sender):
Application.Exit()
Application.Restart()
#self.Refresh()
#self.ResetBindings()
#self.ActiveForm.Close()
sd = PrintSetForm()
sd.ShowDialog()
This gif shows the form in action:
Manage Print Sets
Any ideas or suggestions?
Thank you.
3) If I try to populate the SheetsLb with a DataSource, just the first set clicked is shown.
Sheets=[sheet.Name for sheet in view_set.Views]
SheetNumber=[sheet.get_Parameter(BuiltInParameter.SHEET_NUMBER).AsString() for sheet in view_set.Views]
SheetsLb.BeginUpdate()
SheetsLb.DataSource = None
SheetsLb.Items.Clear()
UpdatedList=[]
for number,name in zip(SheetNumber,Sheets):
UpdatedList.append(number+" - "+ name + " [ ] ")
SheetsLb.DataSource=UpdatedList
SheetsLb.EndUpdate()
1) See if this works:
It would be worth checking that there is something selected in self.viewSetsLb. Ive added a check to the code below
The view_set variable could be initialised as a boolean instead of a list
Using break in the for loop keeps things a little snappier
Ive used the more pythonic for view in PrintSetForm.viewSets rather than for i in PrintSetForm.viewSets - keeping it nice and clear
This code works for me:
self.curItem = self.viewSetsLb.SelectedItem
if not self.viewSetsLb.SelectedItem:
print 'No Printset selected!'
return
view_set = False
for view in PrintSetForm.viewSets:
if view.Name == str(self.curItem):
view_set = view
break
else:
continue
Sheets=[sheet.Name for sheet in view_set.Views]
self.sheetsLb.BeginUpdate()
self.sheetsLb.Items.Clear()
for sheet in Sheets:
self.sheetsLb.Items.Add(sheet)
self.sheetsLb.EndUpdate()
2) Its because the data in your PrintSetForm.ViewSets list is out of date. Every time you change something (ie delete a viewset), repopulate this list:
PrintSetForm.ViewSets = FilteredElementCollector(doc).OfClass(ViewSheetSet).ToElements()
Also, you shouldnt need to build a refresh button, perhaps have a class function that repopulates the Printset list and ListBox, and clears the Sheet ListBox that you call after every action?
Sounds like youre having fun mate!
It sounds as if you have an issue with the scoping and lifetime of variables. For instance, some variables may have a lifetime limited to the form display, and therefore cannot be accessed after the form is closed. You could change the lifetime of these variables, e.g., by making them static class variables instead of local instance variables. I suggest you read up on .net static class variable scope.

-ADVICE REQUEST- MS-ACCESS Hyperlink Comparison Script Advice

I'm brand new to MS-Access and had a few guideline-questions,
My organization uses MS-Access to track a large electronic-part inventory. These parts have a hyperlink field that links to the product webpage. Here's an example:
Part Number Part Type Value Description Component_Height Voltage Tolerance Schematic Part Layout PCB Footprint Manufacturer Part Number Manufacturer Distributor Part Number Distributor Price Availability Link
UMK105CG100DV-F Ceramic 10pF CAP CER 10PF 50V NP0 0402 0.35 MM 50V ±0.5pF xxxxx\C_NP,xxxxx\C_NP_Small c_0402 UMK105CG100DV-F Taiyo Yuden 587-1947-2-ND Digi-Key 0.00378 In Stock http://www.digikey.com/product-detail/en/UMK105CG100DV-F/587-1947-2-ND/1473246
Links Here:
http://www.digikey.com/product-detail/en/UMK105CG100DV-F/587-1947-2-ND/1473246
Nearly the entire majority of our hyperlinks point to the supplier DigiKey.
Right now the verification flow goes like this:
Every month or so a large group of us sits down and one by one copies the hyperlink into google.
We then open the corresponding webpage and verify component availability etc.
We have nearly 1000 components and this process takes hours. All I'm looking for is advice on how to improve our workflow. I was hoping there was say a way to write a "open hyperlink with default browser and search string" macro or scripting interface. The pseudo-script would then check that the string "Quantity Available" was greater than 1, and if it wasn't (the part was out of stock) mark the part as obsolete.
Any advice would be greatly appreciated, I'm really aiming to optimize our workflow.
You can traverse the DOM of the web page. A quick look at the web page and you can see a table with a name of product-details.
So the following VBA code would load the sample web page, and pull out the values.
Option Compare Database
Option Explicit
Enum READYSTATE
READYSTATE_UNINITIALIZED = 0
READYSTATE_LOADING = 1
READYSTATE_LOADED = 2
READYSTATE_INTERACTIVE = 3
READYSTATE_COMPLETE = 4
End Enum
Sub GetWebX()
Dim ie As New InternetExplorer
Dim HTML As New HTMLDocument
Dim strURL As String
Dim Htable As New HTMLDocument
Dim i As Integer
strURL = "http://www.digikey.com/product-detail/en/UMK105CG100DV-F/587-1947-2-ND/1473246"
ie.Navigate strURL
Do While ie.READYSTATE < READYSTATE_COMPLETE
DoEvents
Loop
Set HTML = ie.Document
Set Htable = HTML.getElementById("product-details")
For i = 0 To Htable.Rows.Length - 1
With Htable.Rows(i)
Debug.Print Trim(.Cells(0).innerText), Trim(.Cells(1).innerText)
End With
Next I
ie.Quit
Set ie = Nothing
End Sub
output of above:
Digi-Key Part Number 587-1947-2-ND
Quantity Available 230,000
Can ship immediately
Manufacturer Taiyo Yuden
Manufacturer Part Number UMK105CG100DV-F
Description CAP CER 10PF 50V NP0 0402
Expanded Description 10pF ±0.5pF 50V Ceramic Capacitor C0G, NP0 0402(1005 Metric)
Lead Free Status / RoHS Status Lead free / RoHS Compliant
Moisture Sensitivity Level (MSL) 1 (Unlimited)
Manufacturer Standard Lead Time 11 Weeks
Since the above is a array, then you could place a button right on the form, and have a few extra lines of VBA to write the values into the form. So a user would just have to go to the given record/form in Access - press a button and the above values would be copied right into the form.
the above VBA code requires a reference to:
Microsoft Internet Controls
Microsoft HTML Object Library
I would suggest that after testing you use late binding for the above two libraries.

Only a portion of my front-end users are getting the full functionality of the application

I developed a front-end for a separate department that would allow them to key in data to our back-end table structure. Part of that front-end form includes a message box which opens each time they make a change. To allow them to provide a reason, add the date, etc.
Only certain users are seeing this message box when they use the form. It's not a permissions issue or a compatibility problem with versions of Access. We've looked into that. We're lost as to what it could be.
I know the code we use for the message box uses a particular library in MS Access. Could that be an issue? Anything else that you folks think it might be? We're just looking for possibilities here.
Source Code:
Option Compare Database
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim cmmnt As String
If Me.NewRecord Then
'Calls modAudit function to record new records to Audit Trail
cmmnt = InputBox("What is the reason for adding this record")
If StrPtr(cmmnt) = 0 Then
Me.Undo
Exit Sub
Else
Call AuditChanges("providerID", "NEW", cmmnt)
End If
Else
'Calls modAudit function to record edits to Audit Trail
cmmnt = InputBox("What is the reason for changing the value of this field?")
If StrPtr(cmmnt) = 0 Then
Me.Undo
Exit Sub
Else
Call AuditChanges("providerID", "EDIT", cmmnt)
End If
End If
End Sub

Multi-Session Variables in MS Access

Is there a way to store variables in access which retain their data even after access restarts? The idea is that I will log the date and time of when the form was last opened, which will allow me to only show records since it was last opened.
Since you are inside Access, just create a table to store such information!
In case anyone comes looking here for a method to store Permanent Variables (aka Multi-session Variables) without using Access tables. Here is the techique to achieve this.
Crux : Use TextBox DefautlValue to store data.
Dim strForm As String
Dim frm As Form
strForm = "FormName"
DoCmd.OpenForm strForm, acDesign, , , , acHidden
Set frm = Forms(strForm)
frm.Text0.Caption = "Test"
frm.Text0.DefaultValue = 4
Set frm = Nothing
DoCmd.Close acForm, strForm, acSaveYes
Important Note : Form needs to be open in Design view.

Resources