I have a table in my Access database where I keep track of my jobs. I have a form based on a query based on this table. In my table there is a field called [file_path]. This is a field that controls a web browser on my form.
I would like this field [File_path]to be updated when I update my field [customer_Id] on the form. It should be updated to reflect the customer name together with the file path e.g. C:\Users\Windows8\Documents\Projects\Doe John.
How do I pull the [Customers]![Last_Name] and [Customers]![first_name] into my string in field [file_path]?
I think that I have to use VBA code, but not sure how. I have started with this:
Private Sub Customer_AfterUpdate()
Me.File_path = Me.Last_Name
End Sub
I know that this is a feeble beginning. Does someone know how to help me? Please tell me if my question is not clear.
Beside all this the above code is returning Invalid outside procedure in Private Sub Customer_AfterUpdate(). Why?
Me refers to the form. You are correct that using Me is best practice (speed, ease of coding, etc.), but when I was starting out or even now in a complicated application I like to write it out, because that reminds me not to make little mistakes like this. Or, maybe your memory is better than mine, in which case ignore and read on.
[file_path] is in the table, so you need to access it in the table. Your code looks for it in the form, and realizes that it isn't inside Me, and throws this error.
I am going to give you a line of code below that should be a good starting point for you, but I think you may need to examine your calling event. AfterUpdate is cool, because it just seems to happen automatically, but I don't think you want your field updated every single time anything in the whole "Customer" form is updated. If there is a specific textbox that is always updated last (last_name?), you could try that one instead, but I would be nervous about trying to remember to always make sure that was the last one that I updated... I mean, if one day I accidentally did the name before the customer_id, I would have some serious confusion on my hands later on. Might I suggest a command button, and using the Click event instead?
No matter what event you end up using, you really only need one line of code inside your event. There are plenty of ways of doing this. Might I suggest something along the lines of CurrentDb.Execute "update " & myAwesomeTableNameHere & " set file_path='"C:\Users\Windows8\Documents\Projects\" & forms("customers").controls("last_name").text & " " & forms("customers").controls("first_name").text & "' where customer_id='" & forms("customers").controls("customer_id").text & "'"
Now, a caution: data is precious, and beautiful. The names of the people who pay you are even more so. Changing data in a pre-populated table by free-typing into a textbox on a form sounds like disaster waiting to happen to me. If it were me, I would either 1)make backups very often (easist), or 2)validate your entries multiple ways before writing anything to the table.
Related
I have an access database with two Long Text fields "QAComment" and "NoteComment." We have found that the NoteComment field is rarely used and we want to stop using it, placing the information that might go there within the QAComment Field instead. Every record currently has text in the QAComment field already. What I am trying to do is run an update query that moves the information from NoteComment and appends it onto the Information from QAComment - I cant lose whats already in there. I tried googling for a way to do this but it keeps sending me to basic update queries where the info would get replaced, not added onto. I thought it might be possible to concatenate the two fields together into a third field and then copy that info back to the QAComment field, using
Conc: [QAComment] & " " & "Note comments:" & " " & [Notecomment]
Which works, but I can't figure out how then to use that expression to record that information into the table. I thought I might be able to use the value of the concatenate in the Update, but I cant seem to figure out how to reference it. I also tried just putting the Conc statement in the Update To: but nothing seemed to happen. I'd appreciate anyone who can think of a way to do this.
Sounds like you're building the query in Design View. Switch to SQL View and paste in this text, substituting your table name in place of YourTable
UPDATE YourTable AS y
SET y.QAComment = y.QAComment & " Note comments: " & y.Notecomment
WHERE Len(Trim(y.Notecomment)) > 0;
You can switch back to Design View, if desired, to see how the query is presented there.
The 1,500 page Access 97 Bible (don't laugh!) that I've been given by my boss to solve his problem doesn't solve my problem of how to solve his problem, because it has nee VBA code.
Let me first make clear that I've made attempts to solve this without (much) coding, and that I've coded quite a bit in VBA already, so I'm basically familiar with most things including recordsets, queries, etc etc but have problems with MS Access limits on how to form a report with data coming from VBA variables. I'm also versatile in most programming languages, but this is not a language problem but rather a "how to/what's possible" problem.
My problem right now is that dragging the query fields into the Detail subform and putting them into cells in columns setting Left and Top with VBA code are moving them alright, but each cell is on a new page. Unfortunately, there is multiple data in each cell that won't conform to the Create Report Guide options available.
So my question is simply this: Can someone point me to working examples of code that create, place, and fill with VBA variable strings, text fields at any coordinate I please on a paper size of my choice?
Edit: The above is not an option, as I understand this will prohibit the client from getting an .mde database. What remains, then, is to merely ask for some sound advice on how to get several rows GROUPed BY weekday and machine (see below) into a recordset or similar for each cell. I guess the best way is to count the number of columns in the table (machines in the sql result) and create 5 rows of these with dummy data, then go through the result rows and place the data in the relevant controls. But if you have ideas for doing this work better and faster, write them as answers.
Sorry for this, I knew there was something I wasn't understanding. Basically, I thought Access supported creating reports dynamically via VBA, ie. "generating pages with data" rather than "preparing a flow of controls connected to datasources". But Access requires that you create an ample amount of dummy, unlinked controls manually, then either fill or hide them and that's how they become "dynamic".
This is for Access 2003 on a remote server accessing local and remote ODBC SQL database tables, if relevant. The goal is to make a week schedule of n columns (n=number of machines at a certain plant) x 5 rows (weekday Mon-Fri), and put 1 or more recordset rows (=scheduled activities for that day on that machine) in each of the "n by 5 table" cells.
If you detect venting frustration in this post I can only ask your forgiveness and hope for your understanding.
So, has many techniques for this:
Ex: 1) using dinamic sql for this:
'Create a function to make sql query
Function MakeMySQlReport(Parameters):
Dim strSql as string
Dim strMyVar as string
strsql = vbnullstring
strsql = "Select " & myVar1 & " as MyFieldVar1, * from myTable where Fieldx =" & Parameters
MyReport.recordSource = ssql
End Function
Ex: 2) create function that returns yours strings:
Function MyString1() as string
MyString1 = 'ABC'
end Function
An in your report, select the textbox will receive the value and type =MyString1()]
I hope this help to you, need more examples?
Solution:
Create many objects manually (grr!)
name them systematically
put them in a Control Array (get all Me.Controls, sift out the ones you're interested in, and put them in an indexed array)
go through the array and change their properties
Sorry but I'm not very experienced when it comes to things like this.
I have a table called "Measure Table" with the fields "ID", "Proxy" and "ProxyID".
I created a form based on this table. ID is a label pre-populated from the table. Proxy is a drop down menu with the options "For" or "From". ProxyID contains a drop down with the same numbers as ID.
I would like a user to go to a specific record in the form (say for ID:I800), select "For" from the Proxy drop down and then select ProxyID (lets say L800). For the record for L800, I want it to automatically change the proxy to "From" and the ProxyID to I800.
Is this possible in Access?
Thanks so much for any help provided
Here is a visual of what i wnat to happen:
I want the table to look like this before the update(when the user selects "For" and "L800"):
Record# ID Proxy ProxyID
1 I800 For L800
2 L800
Then the table is automaticaly updated to:
Record# ID Proxy ProxyID
1 I800 For L800
2 L800 From I800
Okay, here is the gist of what you need to do to solve your immediate problem (updating the corresponding row in the other table.
Simply add an event handler to the AfterUpdate event of the form to perform the update to the other row. The code should look very similar to this...
Private Sub Form_AfterUpdate()
Dim RelatedID As String
Dim Proxy As String
If (UCase(Me.Form!Proxy) = "FOR") Then
RelatedID = Me.Form!ProxyID
CurrentID = Me.Form!ID
DoCmd.RunSQL ("UPDATE [Measure Table] SET ProxyID='" & CurrentID & "', Proxy='From' WHERE ID='" & RelatedID & "'")
End If
End Sub
Caveats:
As I mentioned in the comments, this data structure is a very bad idea and will create a lot of extra work for you to maintain the data integrity according to the implicit rules you are specifying as a matter of course with this design. I realize you have an existing DB to deal with, but frankly it would probably be less work to fix the DB design than maintain this one in the long run.
Some additional considerations you didn't ask about, but are going to need to deal with:
What happens if someone updates
either of the entries in a pair
directly in the table instead of
using your form? There really isn't a
good way to apply the above logic to run when
except in the context of using the form.
What happens in this code if the related row doesn't exist for some reason?
What happens if the related row "The FROM" row is updated in the form?
What happens if either row is deleted from the table?
Creating a simple UI using MS Access, hoping to do minimal actual coding (actually helping a friend who is not a coder).
Simplified requirement: Single table, primary key is phone number, lots of other non-mandatory fields. Display a form allowing just the phone number to be entered, if a record with that key exists display the full record, if a record with that key does not exist bring up an form allowing the other fields to be entered for this phone number and hence create a new record.
Q1: Any simple way to achieve this kind of function? Example?
We've got some of this going with a standard form, can execute code if insertion fails, but a standard dialogue box is displayed warning about the duplciate key violation.
Q2: How can we trap that attempted insertion, avoid having the dialogue come up?
You will have to get your hands dirty and write some code to get this outcome. A starting point would be something like this presto code. Post back if you get stuck on any of the parts.
If fCheckIfRecordExists(lYourKey)=True then
Docmd.OpenForm “frmEditExistingRecord”
Else
Docmd.OpenForm “frmEnterNewRecord”
End if
Public function fCheckIfRecordExists (lYourKey as Long) as Boolean
‘Code to check if a record exists, simple method is to use dLookup or a count SQL statement with the criteria as the key you are trying to find
End function
EDIT:
First things first make a form with 1 text box called txtPhone_number and a command button called cmdSearch.
Next put this bit of code in the module behind the form
Public Function fDoes_record_exist(strPhone_number As String) As Boolean
If DCount("Phone_number", "tblYour_table", "Phone_number=" & strPhone_number) > 0 Then
fDoes_record_exist = True
Else
fDoes_record_exist = False
End If
End Function
Next you need to put some code behind the click event of the command button. This code can be expanded on to check for a valid phone number later if you want
If fDoes_record_exist(Me.txtPhone_number) = True Then
DoCmd.OpenForm "frmShow_existing_record"
Else
DoCmd.OpenForm "frmEnter_new_record"
End If
That should set you on your way nicely but post back if you run into problems
Here is an overview of the process with Access logic:
You need an unboud control labelled Phone in the form header, where user will be able to enter the phone number to search. You need to use the After_Update event of that control to trigger your search. There will be a second Phone control, bound this time, in the Detail section of the form for effective data entry/update.
Use the Form_Error event to intercept the error message when user tries to save a duplicate key, in order to display a nice message, and eventually Cancel his changes.
The advice from Kevin Ross to use VB Code is clearly one approach, and I think is appropropriate if we anticipate less trivial requirements in future. However I'm in a situation where I'm helping someone with zero coding background and hence if possible I'd prefer to let them use simple Macros rather than full-scale VB.
As it happens the functionality I require can be implemented with just Macros, and it depends on the suggestion from iDevelop.
The outline of the solution I used:
Create an InitialEntry form with no association to any particular table, it has:
a data entry field for the telephone number
a read-only text box where I can display a message
a button labelled Add
a button labelled Show
I write three macros:
A macro AlreadyExists that displays a message saying "We already that one"
A macro NewEntry that opens a data entry form for my table, in Add mode, and which copies the phone number from InitialEntry!TelephoneNumber
A macro TestForExisting this uses a condition
DCount("*","MyTable","[PhoneNumber] = [FormPhoneNumber] " ) > 0
to control whether to execute AlreadyExists, and a similar test to control whether to call NewEntry.
While this is not as efficient as VB, it does seem to be understandable by a non-coder, so at least we can implement our application.
I'm trying to prevent circular (or even cascading) references in my data, and it seems it's only working part of the time.
In Access 2007, I have the following table:
create table mfr (
mfr_id Autonumber,
mfr_nm Text(255),
mfr_is_alias_for_id Long Integer
)
I'm importing a bunch of data from Excel, and the mfr_nm is one of the columns from the worksheet. I can't control how data gets entered into Excel, so I want a way of capturing alternate spellings as being "really" same thing. So far, so good (I think...).
Now I've built a form off of this table. I've got a ComboBox for the alias--again, so far, so good. However, when I add this code to the BeforeUpdate event, things get "interesting" (error handling omitted):
If Not IsNull(cboMfrAlias) Then
If Not IsNull(DLookup("mfr_is_alias_for_id", "mfr", "mfr_id=" & cboMfrAlias)) Then
MsgBox """Alias for"" must not also be an alias.", vbExclamation
Cancel = True
End If
End If
This works exactly as I expect it to when the form is in Form View, but if I'm in Datasheet View my MsgBox is immediately followed by an Access-generated "No current record" error that is not caught by error handling within the BeforeUpdate sub.
Can I catch this error? Where?
Your dropdown list should filter out entries that are aliases. In other words, don't display a choice the user can't make.
You'd do this by simply eliminating from the dropdown the choices where mfr_is_alias_for_id Is Not Null.
I've implemented this in various guises and it works fine.
I'm addressing the "No Current Record" error part of your question, from so long ago. After checking google for an answer, I found this link which was helpful. However, instead of using NZ() to transform the troublesome binary field in an aggregate query, I used troublesomefield: IIF([troublesomefield] IS NULL,NULL,[troublesomefield]) and this worked to banish the error. So my solution is only a small variation on the original answer I found, but it gets around the error and let you keep nulls if you want to...