MS Access Forum / Modules / DAO / VBA / December 2005
beginner programmer with a problem.
|
|
Thread rating:  |
PeterK - 15 Dec 2005 10:47 GMT I’m a struggling learner on programming and would appreciate some help. This is where I’m up to:
I have read several introductory articles on programming as referred to on this excellent site. As a result I can do one or two basic commands like opening a form, but that’s all, and I still feel I have absolutely no idea of the underlying principles. I compare this with other areas such as using forms or queries, where I have read the help notes and articles and I’m on my way.
I set myself a goal of taking a simple database I created using macros and re-creating it by replacing each macro with code. Here’s one I’m completely stuck on: Opening Form2 from Form1, setting the value of a control, and going to a control.
The macro actions and settings are: Echo (Echo On = No) Close (Object Type = Form; Object Name = Form1; Save = No) OpenForm (Form Name = Form2; View = Form; Data Mode = Add; Window Mode = Normal) SetValue (Item = [Forms]![Form1]![RecordID]; Expression = RecordID) GoToControl (Control Name = Control1)
I started by looking in VB help and searching for SetValue - no references at all. Mental brick wall.
What would help me is if someone could write the above in code, and assume I know nothing (which is pretty accurate) and explain each line to me in a way that gives me the *insight*, the ability to go on to other examples and not be bamboozled by slight changes.
 Signature PeterK
Allen Browne - 15 Dec 2005 11:35 GMT Peter, it looks like your macro is: 1. Hiding screen updates. 2. Closing Form1 without any design changes. 3. Opening Form2 in data entry mode (at a new record). 4. Trying to set the value of the RecordID field on Form1, to whatever RecordID is (possibly the null value from the new record on Form2?)
Step 4 will fail because Form1 is no longer open, so you can't set any value on it.
If you were trying to assign the value from: [Forms]![Form1]![RecordID] to: [Forms]![Form2]![RecordID] you would need to leave Form1 open. The Visual basic code would then be: Forms!Form2!RecordID = Forms!Form1!RecordID
Closing Form1 in VBA would be: DoCmd.Close acForm, "Form1"
Opening a form in VBA is: DoCmd.OpenForm "Form2"
SetFocus is the best way to go to a control, e.g.: Forms!Form2!RecordID.SetFocus
You can turn Echo off in VBA: DoCmd.Echo False BUT, unlike the macro, it does NOT automatically come on again when your code ends. So if something goes wrong you cannot see what happened. Use with caution!
HTH
 Signature Allen Browne - Microsoft MVP. Perth, Western Australia. Tips for Access users - http://allenbrowne.com/tips.html Reply to group, rather than allenbrowne at mvps dot org.
> I'm a struggling learner on programming and would appreciate some help. > This [quoted text clipped - 34 lines] > not > be bamboozled by slight changes. PeterK - 16 Dec 2005 03:40 GMT Thanks for the quick reply, and you are exactly right on step 4. The goal is to set the value in the other direction - from Form1 into Form2.
Now, here is the *insight* issue. I’m putting this down in detail to give you the picture of the conceptual problems I have.
Code 1 and 2 follow. Code 1 I copied from another module. Its purpose is simply to open the form. It works. It has lots of lines and add ons. Some lines I understand in isolation, some not.
Code 2 is me accumulating the single line commands you gave me. It does nothing visible. It certainly didn’t open my second form.
So when I read your reply, I think, each of those lines makes perfect sense. I understand. But the moment I have to work in larger units, I’m lost. It’s the context that gets me - what’s really necessary or not, what definitions you need, etc. How do I make correct use of the code units??
Code 1 reads:
Private Sub cmd_OpenForm2_Click() On Error GoTo Err_cmd_OpenForm2_Click
Dim stDocName As String Dim stLinkCriteria As String stDocName = "Form2" DoCmd.OpenForm stDocName, , , stLinkCriteria
Exit_cmd_OpenForm2_Click: Exit Sub Err_cmd_OpenForm2_Click: MsgBox Err.Description Resume Exit_cmd_OpenForm2_Click End Sub
Code 2 reads:
Private Sub cmd_OpenForm2_Click()
DoCmd.OpenForm "Form2" Forms!Form2!RecordID = Forms!Form1!RecordID DoCmd.Close acForm, "Form1" Forms!Form2!RecordID.SetFocus
End Sub
 Signature PeterK
> Peter, it looks like your macro is: > 1. Hiding screen updates. [quoted text clipped - 69 lines] > > not > > be bamboozled by slight changes. Allen Browne - 16 Dec 2005 07:41 GMT Code 1 looks like the kind of thing the Wizard generates. Most if it is error handler, which you can ignore for now. There is no difference bewteen the whole of Code 1, and the first line of Code 2.
Code 2 line 2 reads: Forms!Form2!RecordID = Forms!Form1!RecordID This sets the field or control named RecordID on Form2 to the same value as the field/control named RecordID on Form1. If you can see a value in RecordID on Form1, but it does not show up after this line on Form2, perhaps it has not been accepted yet.
When you enter something in a text box and move on, Access evaluates the entry. For eample, if you had a text box bound to a Number field, and you entered: four when you press the tab key to move to the next control Access gives you an error message that the value is not right for that type of field. Do you see that the Value is not set until you move from the control? So, if the focus is still in RecordID on Form1, it probably has not yet been evaluated as the Value. Moving focus to the next control will cause it to be accepted, and your line of code should then work in transferring that value to Form2.
Please post back if that is not the issue.
 Signature Allen Browne - Microsoft MVP. Perth, Western Australia. Tips for Access users - http://allenbrowne.com/tips.html Reply to group, rather than allenbrowne at mvps dot org.
> Thanks for the quick reply, and you are exactly right on step 4. The goal > is [quoted text clipped - 134 lines] >> > not >> > be bamboozled by slight changes. PeterK - 18 Dec 2005 03:46 GMT On further investigation I found the problem was a lot simpler - I misspelled the name of the form! I now have code that does something rather than nothing. A second form is opened and a value is set.
I’m taking it from your comments that in fact the best strategy for learning code is the minimalist approach - one line at a time, and only add extra stuff as you discover that it’s really needed.
Your comments on Access accepting values in a field were really helpful.
My problem now is that if I click on the command button on Form1, I only ever get Form2 opened to the same initial record. So my next step I presume is to add options to my code such as a filter statement and defining Edit or Add Data modes. I take it that this was the difference between the patterns in…
DoCmd.OpenForm "Form2"
and…
DoCmd.OpenForm stDocName, , , stLinkCriteria
In VB help I have found ‘OpenForm Method’. I’m currently reading through the various properties listed there and will post again if I can’t work it out.
Question - what’s the difference between an action and a method?
Appreciation - every time I post I get a reply that’s prompt, insightful and useful. Many thanks.
 Signature PeterK
> Code 1 looks like the kind of thing the Wizard generates. > Most if it is error handler, which you can ignore for now. [quoted text clipped - 159 lines] > >> > not > >> > be bamboozled by slight changes. Allen Browne - 18 Dec 2005 04:14 GMT Answers embedded.
 Signature Allen Browne - Microsoft MVP. Perth, Western Australia. Tips for Access users - http://allenbrowne.com/tips.html Reply to group, rather than allenbrowne at mvps dot org.
> On further investigation I found the problem was a lot simpler - I > misspelled > the name of the form! I now have code that does something rather than > nothing. A second form is opened and a value is set. Great. Solved.
> I'm taking it from your comments that in fact the best strategy for > learning > code is the minimalist approach - one line at a time, and only add extra > stuff as you discover that it's really needed. That's really important for debugging. You can turn any line into a comment by adding a single-quote to the start. Once things are working, you can reactivate the line by removing the quote.
> Your comments on Access accepting values in a field were really helpful. > [quoted text clipped - 12 lines] > > DoCmd.OpenForm stDocName, , , stLinkCriteria Without any criteria (and assuming its Data Entry property is No), the form opens to the first record, so you are then changing the RecordID value of the first record.
You can use stLinkCriteria to open it filtered. The string needs to look like the WHERE clause in a query. The form then opens filtered when you use the stLinkCritiera string in the WhereCondition of OpenForm.
> In VB help I have found 'OpenForm Method'. I'm currently reading through > the various properties listed there and will post again if I can't work it > out. > > Question - what's the difference between an action and a method? Action applies in a macro. Method applies in VBA code. Most action have a corresponding method to use in VBA, but not all (e.g. SetValue.)
In VBA, you need to find out what the Method applies to. Most often it's the DoCmd object, e.g.: DoCmd.OpenForm but it might be something else (such as the Application object.) Sometimes there are different choices, e.g. use the Requery method of a form to reload all its records, or the Requery method of a combo/listbox to reload its RowSource.
The help file specifies what the method applies to. There is also an Object Browser to help you know what applies to what: Press F2 in the code window.
> Appreciation - every time I post I get a reply that's prompt, insightful > and > useful. Many thanks. Excellent: that's what it's about.
PeterK - 19 Dec 2005 02:22 GMT ok, I’ve had a go and this is how it’s gone.
These tables are part of a church database and relate to worship/music/songs.
The goal is to add 1 or more themes to a particular song. This is my code:
Private Sub cmd_OpenThemeForm_Click() ' Opens the theme form. ' Edit mode. ' Filters records relating to the active song on the song form. DoCmd.OpenForm frm_Theme, , , Forms!frm_Theme!fld_ThemeAndSongLinkID = Forms!frm_Song!fld_SongID, acFormEdit End Sub
When I ran it I got an error message - “Run time error 2450. Access can’t find the form ‘frm_Theme’. This doesn’t make sense to me - The database window definitely shows that form with the correct spelling.
Any ideas?
 Signature PeterK
> Answers embedded. > [quoted text clipped - 64 lines] > > Excellent: that's what it's about. Allen Browne - 19 Dec 2005 07:39 GMT The OpenForm method expects a string for the name of the form. Since you did not put it in quotes, Access does not understand the name.
The WhereCondition string needs the name of the field (as it appears in the target form's recordsource), with the matching value tacked on.
Try something like this: Dim strWhere as String strWhere = "LinkID = " & Nz(Forms!frm_Song!fld_SongID,0) DoCmd.OpenForm "frm_Theme", , , strWhere
 Signature Allen Browne - Microsoft MVP. Perth, Western Australia. Tips for Access users - http://allenbrowne.com/tips.html Reply to group, rather than allenbrowne at mvps dot org.
> ok, I've had a go and this is how it's gone. > [quoted text clipped - 17 lines] > > Any ideas? PeterK - 20 Dec 2005 04:16 GMT I tried your code like this:
Private Sub cmd_OpenThemeForm_Click() ' Opens the theme form. ' Edit mode. ' Filters records relating to the active song on the song form. Dim strWhere As String strWhere = "fld_ThemeAndSongLinkID = " & Nz(Forms!frm_Song!fld_SongID, 0) DoCmd.OpenForm "frm_Theme", , , strWhere Exit Sub
End Sub
It produced this error message: “Method or data member not found.”
I then tried the simpler version, just opening the form:
Private Sub cmd_OpenThemeForm_Click()
DoCmd.OpenForm "frm_Theme" Exit Sub
End Sub
Same error message.
Now what?
 Signature PeterK
> The OpenForm method expects a string for the name of the form. > Since you did not put it in quotes, Access does not understand the name. [quoted text clipped - 28 lines] > > > > Any ideas? Allen Browne - 20 Dec 2005 04:40 GMT Did you try Compile on the Debug menu (from the code window)?
Is frm_Song open when this code runs?
Is the a control (or field) named "fld_SongID" on that form?
Is there are field named fld_ThemeAndSongLinkID in the table that frm_Theme gets its records from?
Is that a Number type field?
 Signature Allen Browne - Microsoft MVP. Perth, Western Australia. Tips for Access users - http://allenbrowne.com/tips.html Reply to group, rather than allenbrowne at mvps dot org.
>I tried your code like this: > [quoted text clipped - 65 lines] >> > >> > Any ideas? PeterK - 29 Dec 2005 21:56 GMT I have worked through your suggestions and it turns out to be a typing error again. So the code is now working. But - do you have any tips on making names of fields, controls etc consistent, and avoiding those errors when you are writing code?
 Signature PeterK
> Did you try Compile on the Debug menu (from the code window)? > [quoted text clipped - 76 lines] > >> > > >> > Any ideas? Allen Browne - 30 Dec 2005 03:14 GMT Suggestions for coding:
1. Make sure *every* module has: Option Explicit at the top. Access will automatically add this to all new modules if you check the box under: Tools | Options | Editor | Require Variable Declaration (from the code window.)
2. Whenever you are referring to an object on the form you are coding in, use Me rather than Forms!Form1. VBA knows the names of the objects on this form.
3. For controls in a form/report, use the dot (.) rather than the bang (!), e.g.: Me.Text0 VBA will autocomplete the name for your (press Tab to accept the name). This really cuts down the misspelt names, as well as being faster to type. You still need the bang for fields of a recordset. (I personally use the bang for fields from the form's recordset that are not represented by controls on the form, as Access can be inconsistent about recognising these.)
4. Use tab indents for block operations (such as If ... End If). I actually type the End If immediately after the If line, and then jump back up to enter the other lines between them. This cuts down on the chance of mismatched blocks.
5. Always Compile (Debug menu) before running your code.
6. If you use error handlers, disable them until the code is tested, so you can see what line is failing. More info on error handlers: http://allenbrowne.com/ser-23a.html
Heaps of other wider suggestions as well, such as typing as narrowly as possible, scoping as narrowly as possible, thinking event-driven, writing modular (small) reusable procedures, breaking out a process that is likely to error into another function, using the return value of functions to indicate success/failure if nothing else is obvious, naming conventions, always handling Null, remembering the "other" possibility (e.g. Case Else), cleaning up, testing and debugging at each stage, handling extreme/unexpected values, etc, etc.
 Signature Allen Browne - Microsoft MVP. Perth, Western Australia. Tips for Access users - http://allenbrowne.com/tips.html Reply to group, rather than allenbrowne at mvps dot org.
>I have worked through your suggestions and it turns out to be a typing >error > again. So the code is now working. But - do you have any tips on making > names of fields, controls etc consistent, and avoiding those errors when > you > are writing code? PeterK - 30 Dec 2005 22:56 GMT Thanks for all your advice... that should keep me going for a year or 2!!
 Signature PeterK
> Suggestions for coding: > [quoted text clipped - 43 lines] > > you > > are writing code? Klatuu - 15 Dec 2005 13:19 GMT One thing that can help you learn VBA is to take convert the macros you have written to VBA. Study the code and compare it to the macro. You will start to see how some things work. Start a "Function of the Day" schedule. Every day, pick a function you are not familiar with, read up on it in VBA Help (Access Help doesn't, much), try it out. And, continue to read and post to this site. Good Luck.
> I’m a struggling learner on programming and would appreciate some help. This > is where I’m up to: [quoted text clipped - 26 lines] > that gives me the *insight*, the ability to go on to other examples and not > be bamboozled by slight changes.
|
|
|