|
|
I develop software for schools. The system is quite an extensive database. It contains over 100 forms with an average of about 8 printed pages of coding per form. I distribute the software with a runtime version of Microsoft Access 2000.
With all these forms and coding, I'm being haunted my minor bugs that keep popping up now and then that close down the database, so the users have to restart the system.
I keep fixing the bugs one by one, but it seems like a never ending project. Most of the bugs are initiated by students interactively doing things I never imagined they could do.
My question is if I just put in the statement "End Sub" in the Err_XXXX: subroutines instead of the message statement will that prevent a minor error from shutting down the system. Is there anything else I can easily do to reduce the number of terminal problems?
Any help would be appreciated. Thanks
-- Frank Wagner fwagner111[ at ]aol.com
|
|
Frank Wagner wrote:
[Quoted Text] > I develop software for schools. The system is quite an extensive > database. It contains over 100 forms with an average of about 8 > printed pages of coding per form. I distribute the software with a > runtime version of Microsoft Access 2000. > > With all these forms and coding, I'm being haunted my minor bugs that > keep popping up now and then that close down the database, so the > users have to restart the system. > > I keep fixing the bugs one by one, but it seems like a never ending > project. Most of the bugs are initiated by students interactively > doing things I never imagined they could do. > > My question is if I just put in the statement "End Sub" in the > Err_XXXX: subroutines instead of the message statement will that > prevent a minor error from shutting down the system. Is there > anything else I can easily do to reduce the number of terminal > problems? > > Any help would be appreciated. Thanks
All research indicates that all software has bugs and at least one major IBM study claims there is about a 50% chance that fixing a bug will cause or uncover another one. (Try Scott Rosenberg's "Dreaming in code" to see you are not alone)
My first suggestion is to see how much code you can get rid of. I wrote a report card program in Mbasic a "few" years ago for a TRS Mod III and don't think it ran 8 pages.
If you are looping through records make sure you can't do it with a query. Whre were you in working with a reltional model when you started this package?
My attendance package looks like a paper based one, marks week ends and holidays, has less than 8 pages behind the forms.
|
|
Well, if you always distribute a mde, then un-handled errors don't shut down access, and you do not loose any local or global vars.
Remember, one un-handled error and ALL LOCAL + GLOBAL vars will be lost. This means you application can become quite un-reliable unless EVERY routine has error handling.
However, while you could put error handling in every singe routine, why not just use a mde? Keep in mind that a mde NEVER looses it variables even with NO error handling and a error occurs. This just results in a far more reliable application.
And, using a mde also means that access does not shut down either. I never used the 2000 runtime, but I used 2003 and 2007. In these cases a mde (or accde) that has a runtime error does NOT force the application to shut down. I don't believe that the 2000 runtime is any different here.
While I do suggest that you have good error handling, I am of the view that one does not need to have error handling absolute every routine, especially when you use a mde.
So, if you are not using a mde, that would likely the best step you could take to improve reliability. And, a mde is smaller, and runs faster, and it can't become un-compiled which will reduce bloat.
-- Albert D. Kallal (Access MVP) Edmonton, Alberta Canada pleaseNOOSpamKallal[ at ]msn.com
|
|
Are you, in fact, compiling your code prior to distribution? This should help pinpoint errors and allow you to correct them before the great unwashed are given access.
-- There's ALWAYS more than one way to skin a cat!
Answers/posts based on Access 2000/2003
Message posted via http://www.accessmonster.com
|
|
"Linq Adams via AccessMonster.com" <u28780[ at ]uwe> wrote in message news:8e9f64a6219bd[ at ]uwe...
[Quoted Text] > Are you, in fact, compiling your code prior to distribution? This should > help > pinpoint errors and allow you to correct them before the great unwashed > are > given access. >
Keep in mind that while you can compile your code before you distribute it by going debug->compile from the code menu, keep in mind that if you distribute a mdb, then any on handled error will cause your to lose all application to loose all variable values.
More importantly and more specific to this issue, is the posters said that he's distributing via the runtime and errors are causing his application to shut down. Keep in mind that any un- handled error in the runtime is a much worse affair, since it causes the whole thing to SHUT DOWN.
This shutdown occurs right after the users clicks to dismiss the dialog box that pops up when you got an error.
So while in the regular version of access a un handled error causes you to blow out all your local and global variables, when it occurs in the runtime, it not only loses all the variables, when you click OK to dismiss the dialog box that tells you about the error, the whole access runtime actually terminates and shuts down.
The user at this point will then have to relaunch the application and it also possbile they lost some work.
So we're not talking about compiling errors in the code, we are talking about code without error handling....
My whole point here is that if the user uses a mde, not only do variables never get blown out, but in the runtime those un-handled errors does not cause the whole system to shut down.
This 100% shutting down of MS access is normal and typical behavior when you deploy a regular mdb file with the runtime.So, there is two significant and important benefits to distributing your application as an mde.
So, the issue of making sure one's code having compile errors is important, but not compile errors, but un-handled errors in the runtime that causes this shutdown.
-- Albert D. Kallal (Access MVP) Edmonton, Alberta Canada pleaseNOOSpamKallal[ at ]msn.com
|
|
Hi Frank
You've already got some good replies to your question, but there's one aspect I did not quite follow here.
You say that the bugs "close down the database so the users have to restart." This should not be the case.
That will happen if you use code without error handling, or if you use macros (since they don't have error handling.) But you also talk about the "Err_XXXX:" label, which suggests you do have error handling in your code. Handled errors should not cause the system to shut down (unless we are talking about things it can't recover from that keep triggering errors such as getting disconnected from the network where the data is.)
The short answer to your question is, No: adding "End Sub" in the error handling is not an ideal way to avoid errors. You certainly need "Exit Sub/Function" above the error handler, and you need some kind of Resume in the error handler. The error handler itself needs to be really simple, without anything that can fail (since nothing handles errors that occur in its code.)
When using the runtime, it is crucial that every procedure uses error handling. My suggestion would be to log the errors, so you can see exactly what's going on, and so address the issues that arise. I think you'll find this more informative that relying on users to tell you what they did and what error occurred. Here's the approach I use: Error Handling in VBA at: http://allenbrowne.com/ser-23a.html Only a couple of times a year do I request a user to send me their error log, but it can be really helpful.
More broadly, though, if an error is closing the system down, something else is going wrong. If you are still stuck, give us an example of the kind of error that's crashing your software.
-- 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.
"Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message news:9B3538DC-5FD1-4DE5-8890-5288CB1691F7[ at ]microsoft.com...
[Quoted Text] >I develop software for schools. The system is quite an extensive database. > It contains over 100 forms with an average of about 8 printed pages of > coding > per form. I distribute the software with a runtime version of Microsoft > Access 2000. > > With all these forms and coding, I'm being haunted my minor bugs that keep > popping up now and then that close down the database, so the users have to > restart the system. > > I keep fixing the bugs one by one, but it seems like a never ending > project. > Most of the bugs are initiated by students interactively doing things I > never imagined they could do. > > My question is if I just put in the statement "End Sub" in the Err_XXXX: > subroutines instead of the message statement will that prevent a minor > error > from shutting down the system. Is there anything else I can easily do to > reduce the number of terminal problems? > > Any help would be appreciated. Thanks > > -- > Frank Wagner > fwagner111[ at ]aol.com
|
|
"Albert D. Kallal" <PleaseNOOOsPAMmkallal[ at ]msn.com> wrote in news:#$K#exWXJHA.3808[ at ]TK2MSFTNGP05.phx.gbl:
[Quoted Text] > Remember, one un-handled error and ALL LOCAL + GLOBAL vars will be > lost. This means you application can become quite un-reliable > unless EVERY routine has error handling.
Not true. Not every routine needs an error handler, but every routine needs to be called in a context in which an error handler is active. That means a top-level subroutine with an error handler can call subroutines without them.
My rule is that subroutines with no outside dependencies have no error handlers. And it works pretty well.
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
Wow!
I would like to thank everyone for their thoughts. Let me take them one at a time and see if I can sort it out.
I'm not sure what an mde that Albert refers to is. I distribute the application using Sage software which packages the Runtime version of the database so my users don't have to have a full version of Access loaded on their computers. When an error that is not specifically referred in an error handling routine occurs. The system gives the user a message that the code failed and then the database closes. How do I create an mde? Is this a different form of packaging an access database?
With regard to the error handler coding, my question is if I use the following code in the error handler will it keep it from shutting down. Two common errors that I encounter are "Invalid use of null" and "Can't move focus to control A". Others occur also, but not as frequently. My question is will placing the following type of general code in the error handler which merely exits the routine keep it from shutting down. My intent is to maybe use it for all interactive controls so the user will see that nothing happened, and they need to use a different response.
Exit_Error: Exit Sub
Err_Error: 'MsgBox Err.Description 'The Old code which is dropped Resume Exit_Error
With regard to the error log, that makes a lot of sense if I can get it to log the error without shutting down the system. Is there any standard code to create such an error log?
I appreciate the thoughts and would like to have you all stay with me so I can come to a workable solution. -- Frank Wagner fwagner111[ at ]aol.com
"Allen Browne" wrote:
[Quoted Text] > Hi Frank > > You've already got some good replies to your question, but there's one > aspect I did not quite follow here. > > You say that the bugs "close down the database so the users have to > restart." This should not be the case. > > That will happen if you use code without error handling, or if you use > macros (since they don't have error handling.) But you also talk about the > "Err_XXXX:" label, which suggests you do have error handling in your code. > Handled errors should not cause the system to shut down (unless we are > talking about things it can't recover from that keep triggering errors such > as getting disconnected from the network where the data is.) > > The short answer to your question is, No: adding "End Sub" in the error > handling is not an ideal way to avoid errors. You certainly need "Exit > Sub/Function" above the error handler, and you need some kind of Resume in > the error handler. The error handler itself needs to be really simple, > without anything that can fail (since nothing handles errors that occur in > its code.) > > When using the runtime, it is crucial that every procedure uses error > handling. My suggestion would be to log the errors, so you can see exactly > what's going on, and so address the issues that arise. I think you'll find > this more informative that relying on users to tell you what they did and > what error occurred. Here's the approach I use: > Error Handling in VBA > at: > http://allenbrowne.com/ser-23a.html> Only a couple of times a year do I request a user to send me their error > log, but it can be really helpful. > > More broadly, though, if an error is closing the system down, something else > is going wrong. If you are still stuck, give us an example of the kind of > error that's crashing your software. > > -- > 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. > > "Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message > news:9B3538DC-5FD1-4DE5-8890-5288CB1691F7[ at ]microsoft.com... > >I develop software for schools. The system is quite an extensive database. > > It contains over 100 forms with an average of about 8 printed pages of > > coding > > per form. I distribute the software with a runtime version of Microsoft > > Access 2000. > > > > With all these forms and coding, I'm being haunted my minor bugs that keep > > popping up now and then that close down the database, so the users have to > > restart the system. > > > > I keep fixing the bugs one by one, but it seems like a never ending > > project. > > Most of the bugs are initiated by students interactively doing things I > > never imagined they could do. > > > > My question is if I just put in the statement "End Sub" in the Err_XXXX: > > subroutines instead of the message statement will that prevent a minor > > error > > from shutting down the system. Is there anything else I can easily do to > > reduce the number of terminal problems? > > > > Any help would be appreciated. Thanks > > > > -- > > Frank Wagner > > fwagner111[ at ]aol.com > >
|
|
Regarding error handling, the example on this page covers it: Error Handling in VBA at: http://allenbrowne.com/ser-23a.html It should *not* close your application down if you are handling the errors.
To help you quickly insert an error handler of your own choosing into any procedure, consider installing mztools: http://www.mztools.com/v3/mztools3.aspx
Regarding debugging 'invalid use of Null', see: Common errors with Null at: http://allenbrowne.com/casu-12.html
Re "can't move focus" errors, there could be several reasons, so the trick will be to identify the cause and find an alternative approach. Examples of a possible cause: a) target control is disabled or not visible b) validation not met for the current control c) wrong event (e.g. in BeforeUpate of KeyDown of this control) d) record cannot be saved (if trying to move into subform) e) other events are preventing the SetFocus from working.
Regarding an MDB file: it contains 2 versions of the code: - the text version (what you read and edit); - the 'compiled' version (semi-machine code that actually runs.)
An MDE contains only the compiled code. Users cannot read or modify the code if you give them an MDE. They can't switch the forms or reports to design view either.
To create an MDE in Access 2000 - 2003, go to Tools | Database Utilities. It's that easy (assuming your code is compilable.) Make sure you keep your MDB as well: otherwise you won't have anything to edit.
MDEs are not backwards compatible. For a database in Access 2000 format, you must use Access 2000 to create the MDE, and it can then be used by A2000, 2002, 2003, or 2007. For a database in A2002/3 format, you can create an MDE using A2002 (usable by A2002, 2003 or 2007) or using A2003 (usable by A2003 or 2007 only.)
After creating the MDE, you will want to set some other properties, e.g. to prevent the user holding down Shift to bypass the startup, or pressing F11 to see the database window. The code below does that.
Function StartupProps(bSet As Boolean) Dim dbData As DAO.Database Dim strDb As String
'Assumes the MDE file is in the same folder _ and has the same name as this one. strDb = DBEngine(0)(0).Name If strDb Like "*.mdb" Then strDb = Left$(strDb, Len(strDb) - 1) & "e" Else Debug.Print "NOT SET" Exit Function End If
'Open the database Set dbData = OpenDatabase(strDb)
' ChangeProperty dbData, "AllowBuiltinToolbars", dbBoolean, False ' ChangeProperty dbData, "AllowBreakIntoCode", dbBoolean, False ' Call ChangeProperty(dbData, "AllowFullMenus", dbBoolean, bSet) ChangeProperty dbData, "StartupShowDBWindow", dbBoolean, False Call ChangeProperty(dbData, "AllowSpecialKeys", dbBoolean, bSet) Call ChangeProperty(dbData, "AllowBypassKey", dbBoolean, bSet)
dbData.Close Set dbData = Nothing End Function
Function ChangeProperty(dbs As Database, strPropName As String, _ varPropType As Variant, varPropValue As Variant) As Integer Dim prp As Property Const conPropNotFoundError = 3270
On Error GoTo Change_Err dbs.Properties(strPropName) = varPropValue ChangeProperty = True Debug.Print strPropName & " is " & varPropValue
Change_Bye: Exit Function
Change_Err: If Err = conPropNotFoundError Then ' Property not found. Set prp = dbs.CreateProperty(strPropName, _ varPropType, varPropValue) dbs.Properties.Append prp Resume Next Else ' Unknown error. ChangeProperty = False Resume Change_Bye End If End Function
-- 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.
"Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message news:2DFC4127-B0B8-43A9-BB64-E5CE8CB4FFA7[ at ]microsoft.com...
[Quoted Text] > Wow! > > I would like to thank everyone for their thoughts. Let me take them one > at > a time and see if I can sort it out. > > I'm not sure what an mde that Albert refers to is. I distribute the > application using Sage software which packages the Runtime version of the > database so my users don't have to have a full version of Access loaded on > their computers. When an error that is not specifically referred in an > error > handling routine occurs. The system gives the user a message that the > code > failed and then the database closes. How do I create an mde? Is this a > different form of packaging an access database? > > With regard to the error handler coding, my question is if I use the > following code in the error handler will it keep it from shutting down. > Two > common errors that I encounter are "Invalid use of null" and "Can't move > focus to control A". Others occur also, but not as frequently. My > question > is will placing the following type of general code in the error handler > which > merely exits the routine keep it from shutting down. My intent is to > maybe > use it for all interactive controls so the user will see that nothing > happened, and they need to use a different response. > > Exit_Error: > Exit Sub > > Err_Error: > 'MsgBox Err.Description 'The Old code which is > dropped > > Resume Exit_Error > > With regard to the error log, that makes a lot of sense if I can get it to > log the error without shutting down the system. Is there any standard > code > to create such an error log? > > I appreciate the thoughts and would like to have you all stay with me so I > can come to a workable solution. > -- > Frank Wagner > fwagner111[ at ]aol.com > > > "Allen Browne" wrote: > >> Hi Frank >> >> You've already got some good replies to your question, but there's one >> aspect I did not quite follow here. >> >> You say that the bugs "close down the database so the users have to >> restart." This should not be the case. >> >> That will happen if you use code without error handling, or if you use >> macros (since they don't have error handling.) But you also talk about >> the >> "Err_XXXX:" label, which suggests you do have error handling in your >> code. >> Handled errors should not cause the system to shut down (unless we are >> talking about things it can't recover from that keep triggering errors >> such >> as getting disconnected from the network where the data is.) >> >> The short answer to your question is, No: adding "End Sub" in the error >> handling is not an ideal way to avoid errors. You certainly need "Exit >> Sub/Function" above the error handler, and you need some kind of Resume >> in >> the error handler. The error handler itself needs to be really simple, >> without anything that can fail (since nothing handles errors that occur >> in >> its code.) >> >> When using the runtime, it is crucial that every procedure uses error >> handling. My suggestion would be to log the errors, so you can see >> exactly >> what's going on, and so address the issues that arise. I think you'll >> find >> this more informative that relying on users to tell you what they did and >> what error occurred. Here's the approach I use: >> Error Handling in VBA >> at: >> http://allenbrowne.com/ser-23a.html>> Only a couple of times a year do I request a user to send me their error >> log, but it can be really helpful. >> >> More broadly, though, if an error is closing the system down, something >> else >> is going wrong. If you are still stuck, give us an example of the kind of >> error that's crashing your software. >> >> "Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message >> news:9B3538DC-5FD1-4DE5-8890-5288CB1691F7[ at ]microsoft.com... >> >I develop software for schools. The system is quite an extensive >> >database. >> > It contains over 100 forms with an average of about 8 printed pages of >> > coding >> > per form. I distribute the software with a runtime version of >> > Microsoft >> > Access 2000. >> > >> > With all these forms and coding, I'm being haunted my minor bugs that >> > keep >> > popping up now and then that close down the database, so the users have >> > to >> > restart the system. >> > >> > I keep fixing the bugs one by one, but it seems like a never ending >> > project. >> > Most of the bugs are initiated by students interactively doing things I >> > never imagined they could do. >> > >> > My question is if I just put in the statement "End Sub" in the >> > Err_XXXX: >> > subroutines instead of the message statement will that prevent a minor >> > error >> > from shutting down the system. Is there anything else I can easily do >> > to >> > reduce the number of terminal problems? >> > >> > Any help would be appreciated. Thanks >> > >> > -- >> > Frank Wagner >> > fwagner111[ at ]aol.com
|
|
"Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message news:2DFC4127-B0B8-43A9-BB64-E5CE8CB4FFA7[ at ]microsoft.com...
[Quoted Text] > > I'm not sure what an mde that Albert refers to is. I distribute the > application using Sage software which packages the Runtime version of the > database so my users don't have to have a full version of Access loaded on > their computers. When an error that is not specifically referred in an > error > handling routine occurs. The system gives the user a message that the > code > failed and then the database closes. How do I create an mde? Is this a > different form of packaging an access database?
go: Tools->database utilities->make mde file
Yes, a mde is a compiled version of your software. Not only does it ensure your code is compiled, but it also prevents your end users from modify the forms and even viewing the code. While the runtime can't modify your code/forms, if that user happens to have the FULL version of ms-access, they will be able to view and modify your forms if you use a mdb, so one should use a mde (this prevents users from seeing or modifying your code).
AS MENTIONED, a bonus is that a mde means your ERRORS WILL NOT SHUT DOWN your runtime application.
I speak about using a mde here:
http://www.members.shaw.ca/AlbertKallal/Articles/split/index.htm
-- Albert D. Kallal (Access MVP) Edmonton, Alberta Canada pleaseNOOSpamKallal[ at ]msn.com
|
|
Mike:
Thanks for the rule on dependencies. It makes sense to me and I'll try to use it. -- Frank Wagner fwagner111[ at ]aol.com
"David W. Fenton" wrote:
[Quoted Text] > "Albert D. Kallal" <PleaseNOOOsPAMmkallal[ at ]msn.com> wrote in > news:#$K#exWXJHA.3808[ at ]TK2MSFTNGP05.phx.gbl: > > > Remember, one un-handled error and ALL LOCAL + GLOBAL vars will be > > lost. This means you application can become quite un-reliable > > unless EVERY routine has error handling. > > Not true. Not every routine needs an error handler, but every > routine needs to be called in a context in which an error handler is > active. That means a top-level subroutine with an error handler can > call subroutines without them. > > My rule is that subroutines with no outside dependencies have no > error handlers. And it works pretty well. > > -- > David W. Fenton http://www.dfenton.com/ > usenet at dfenton dot com http://www.dfenton.com/DFA/>
|
|
Albert:
Thanks for the information about mde. I had never known of this option. If you look at my reply to Allen, it was intended for you also.
I've got a lot to absorb now, so let me try a few things and get back to you guys
Thanks again -- Frank Wagner fwagner111[ at ]aol.com
"Albert D. Kallal" wrote:
[Quoted Text] > "Linq Adams via AccessMonster.com" <u28780[ at ]uwe> wrote in message > news:8e9f64a6219bd[ at ]uwe... > > Are you, in fact, compiling your code prior to distribution? This should > > help > > pinpoint errors and allow you to correct them before the great unwashed > > are > > given access. > > > > > Keep in mind that while you can compile your code before you distribute it > by going debug->compile from the code menu, keep in mind that if you > distribute a mdb, then any on handled error will cause your to lose all > application to loose all variable values. > > More importantly and more specific to this issue, is the posters said that > he's distributing via the runtime and errors are causing his application to > shut down. Keep in mind that any un- handled error in the runtime is a much > worse affair, since it causes the whole thing to SHUT DOWN. > > This shutdown occurs right after the users clicks to dismiss the dialog > box that pops up when you got an error. > > So while in the regular version of access a un handled error causes you to > blow out all your local and global variables, when it occurs in the runtime, > it not only loses all the variables, when you click OK to dismiss the dialog > box that tells you about the error, the whole access runtime actually > terminates and shuts down. > > The user at this point will then have to relaunch the > application and it also possbile they lost some work. > > So we're not talking about compiling errors in the code, we are talking > about code without error handling.... > > My whole point here is that if the user uses a mde, not only do variables > never get blown out, but in the runtime those un-handled errors does not > cause the whole system to shut down. > > This 100% shutting down of MS access is normal and typical behavior when you > deploy a regular mdb file with the runtime.So, there is > two significant and important benefits to distributing your > application as an mde. > > So, the issue of making sure one's code having compile errors is important, > but not compile errors, but un-handled errors in the runtime that causes > this shutdown. > > > -- > Albert D. Kallal (Access MVP) > Edmonton, Alberta Canada > pleaseNOOSpamKallal[ at ]msn.com > > > >
|
|
Albert:
Thanks. I never knew what mbe meant. I tried it and it works great.
So my plan now is to create an mbe database whenever I want to distribute a new version, and use that with the Sage software to create distributable software for my clients.
I will continue development with the mbd database, and convert it to mbe whenever I want to distribute a new verson. Allen has given me a number of thoughts about debugging that I also hope to implement.
Just so everyone knows, I always compile my database regularly, and also compact and repair it before I distribute a new version.
You folks that support this newsgroup are wonderful. Without your help I probably would have given up trying to develop math software years ago.
Thanks -- Frank Wagner fwagner111[ at ]aol.com
"Albert D. Kallal" wrote:
[Quoted Text] > "Linq Adams via AccessMonster.com" <u28780[ at ]uwe> wrote in message > news:8e9f64a6219bd[ at ]uwe... > > Are you, in fact, compiling your code prior to distribution? This should > > help > > pinpoint errors and allow you to correct them before the great unwashed > > are > > given access. > > > > > Keep in mind that while you can compile your code before you distribute it > by going debug->compile from the code menu, keep in mind that if you > distribute a mdb, then any on handled error will cause your to lose all > application to loose all variable values. > > More importantly and more specific to this issue, is the posters said that > he's distributing via the runtime and errors are causing his application to > shut down. Keep in mind that any un- handled error in the runtime is a much > worse affair, since it causes the whole thing to SHUT DOWN. > > This shutdown occurs right after the users clicks to dismiss the dialog > box that pops up when you got an error. > > So while in the regular version of access a un handled error causes you to > blow out all your local and global variables, when it occurs in the runtime, > it not only loses all the variables, when you click OK to dismiss the dialog > box that tells you about the error, the whole access runtime actually > terminates and shuts down. > > The user at this point will then have to relaunch the > application and it also possbile they lost some work. > > So we're not talking about compiling errors in the code, we are talking > about code without error handling.... > > My whole point here is that if the user uses a mde, not only do variables > never get blown out, but in the runtime those un-handled errors does not > cause the whole system to shut down. > > This 100% shutting down of MS access is normal and typical behavior when you > deploy a regular mdb file with the runtime.So, there is > two significant and important benefits to distributing your > application as an mde. > > So, the issue of making sure one's code having compile errors is important, > but not compile errors, but un-handled errors in the runtime that causes > this shutdown. > > > -- > Albert D. Kallal (Access MVP) > Edmonton, Alberta Canada > pleaseNOOSpamKallal[ at ]msn.com > > > >
|
|
Allen:
Thanks.
I've tried using mbe and kick myself for not using it earlier. That should solve a great many problems, including shutting down the database for minor bugs.
I understand you comments about error handling, and will be working on making sure errors are logged as a part of the system. Thanks for leading me to the code for doing that. One question I had is how do you capture the name of the calling procedure?
Focus control is one thing that drives me crazy. Do you know of any good source of information for me to study? One problem that haunts me is when a student enters the wrong answer, the focus doesn't want to return to the same answer control even if I instruct it to with the "Set Focus" command. I have to jump through hoops to get it back to the same spot.
As I mentioned to Albert, you folks are great and I really appreciate your help. Without that help, I would have given up developing software for students years ago.
By the way, my daughter attended the University of Notre Dame branch in Perth a number of years ago. She loved the area. It's beautiful.
Thanks again. -- Frank Wagner fwagner111[ at ]aol.com
"Allen Browne" wrote:
[Quoted Text] > Regarding error handling, the example on this page covers it: > Error Handling in VBA > at: > http://allenbrowne.com/ser-23a.html> It should *not* close your application down if you are handling the errors. > > To help you quickly insert an error handler of your own choosing into any > procedure, consider installing mztools: > http://www.mztools.com/v3/mztools3.aspx> > Regarding debugging 'invalid use of Null', see: > Common errors with Null > at: > http://allenbrowne.com/casu-12.html> > Re "can't move focus" errors, there could be several reasons, so the trick > will be to identify the cause and find an alternative approach. Examples of > a possible cause: > a) target control is disabled or not visible > b) validation not met for the current control > c) wrong event (e.g. in BeforeUpate of KeyDown of this control) > d) record cannot be saved (if trying to move into subform) > e) other events are preventing the SetFocus from working. > > Regarding an MDB file: it contains 2 versions of the code: > - the text version (what you read and edit); > - the 'compiled' version (semi-machine code that actually runs.) > > An MDE contains only the compiled code. Users cannot read or modify the code > if you give them an MDE. They can't switch the forms or reports to design > view either. > > To create an MDE in Access 2000 - 2003, go to Tools | Database Utilities. > It's that easy (assuming your code is compilable.) Make sure you keep your > MDB as well: otherwise you won't have anything to edit. > > MDEs are not backwards compatible. For a database in Access 2000 format, you > must use Access 2000 to create the MDE, and it can then be used by A2000, > 2002, 2003, or 2007. For a database in A2002/3 format, you can create an MDE > using A2002 (usable by A2002, 2003 or 2007) or using A2003 (usable by A2003 > or 2007 only.) > > After creating the MDE, you will want to set some other properties, e.g. to > prevent the user holding down Shift to bypass the startup, or pressing F11 > to see the database window. The code below does that. > > > Function StartupProps(bSet As Boolean) > Dim dbData As DAO.Database > Dim strDb As String > > 'Assumes the MDE file is in the same folder _ > and has the same name as this one. > strDb = DBEngine(0)(0).Name > If strDb Like "*.mdb" Then > strDb = Left$(strDb, Len(strDb) - 1) & "e" > Else > Debug.Print "NOT SET" > Exit Function > End If > > 'Open the database > Set dbData = OpenDatabase(strDb) > > ' ChangeProperty dbData, "AllowBuiltinToolbars", dbBoolean, False > ' ChangeProperty dbData, "AllowBreakIntoCode", dbBoolean, False > ' Call ChangeProperty(dbData, "AllowFullMenus", dbBoolean, bSet) > ChangeProperty dbData, "StartupShowDBWindow", dbBoolean, False > Call ChangeProperty(dbData, "AllowSpecialKeys", dbBoolean, bSet) > Call ChangeProperty(dbData, "AllowBypassKey", dbBoolean, bSet) > > dbData.Close > Set dbData = Nothing > End Function > > Function ChangeProperty(dbs As Database, strPropName As String, _ > varPropType As Variant, varPropValue As Variant) As Integer > Dim prp As Property > Const conPropNotFoundError = 3270 > > On Error GoTo Change_Err > dbs.Properties(strPropName) = varPropValue > ChangeProperty = True > Debug.Print strPropName & " is " & varPropValue > > Change_Bye: > Exit Function > > Change_Err: > If Err = conPropNotFoundError Then ' Property not found. > Set prp = dbs.CreateProperty(strPropName, _ > varPropType, varPropValue) > dbs.Properties.Append prp > Resume Next > Else > ' Unknown error. > ChangeProperty = False > Resume Change_Bye > End If > End Function > > -- > 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. > > "Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message > news:2DFC4127-B0B8-43A9-BB64-E5CE8CB4FFA7[ at ]microsoft.com... > > Wow! > > > > I would like to thank everyone for their thoughts. Let me take them one > > at > > a time and see if I can sort it out. > > > > I'm not sure what an mde that Albert refers to is. I distribute the > > application using Sage software which packages the Runtime version of the > > database so my users don't have to have a full version of Access loaded on > > their computers. When an error that is not specifically referred in an > > error > > handling routine occurs. The system gives the user a message that the > > code > > failed and then the database closes. How do I create an mde? Is this a > > different form of packaging an access database? > > > > With regard to the error handler coding, my question is if I use the > > following code in the error handler will it keep it from shutting down. > > Two > > common errors that I encounter are "Invalid use of null" and "Can't move > > focus to control A". Others occur also, but not as frequently. My > > question > > is will placing the following type of general code in the error handler > > which > > merely exits the routine keep it from shutting down. My intent is to > > maybe > > use it for all interactive controls so the user will see that nothing > > happened, and they need to use a different response. > > > > Exit_Error: > > Exit Sub > > > > Err_Error: > > 'MsgBox Err.Description 'The Old code which is > > dropped > > > > Resume Exit_Error > > > > With regard to the error log, that makes a lot of sense if I can get it to > > log the error without shutting down the system. Is there any standard > > code > > to create such an error log? > > > > I appreciate the thoughts and would like to have you all stay with me so I > > can come to a workable solution. > > -- > > Frank Wagner > > fwagner111[ at ]aol.com > > > > > > "Allen Browne" wrote: > > > >> Hi Frank > >> > >> You've already got some good replies to your question, but there's one > >> aspect I did not quite follow here. > >> > >> You say that the bugs "close down the database so the users have to > >> restart." This should not be the case. > >> > >> That will happen if you use code without error handling, or if you use > >> macros (since they don't have error handling.) But you also talk about > >> the > >> "Err_XXXX:" label, which suggests you do have error handling in your > >> code. > >> Handled errors should not cause the system to shut down (unless we are > >> talking about things it can't recover from that keep triggering errors > >> such > >> as getting disconnected from the network where the data is.) > >> > >> The short answer to your question is, No: adding "End Sub" in the error > >> handling is not an ideal way to avoid errors. You certainly need "Exit > >> Sub/Function" above the error handler, and you need some kind of Resume > >> in > >> the error handler. The error handler itself needs to be really simple, > >> without anything that can fail (since nothing handles errors that occur > >> in > >> its code.) > >> > >> When using the runtime, it is crucial that every procedure uses error > >> handling. My suggestion would be to log the errors, so you can see > >> exactly > >> what's going on, and so address the issues that arise. I think you'll > >> find > >> this more informative that relying on users to tell you what they did and > >> what error occurred. Here's the approach I use: > >> Error Handling in VBA > >> at: > >> http://allenbrowne.com/ser-23a.html> >> Only a couple of times a year do I request a user to send me their error > >> log, but it can be really helpful. > >> > >> More broadly, though, if an error is closing the system down, something > >> else > >> is going wrong. If you are still stuck, give us an example of the kind of > >> error that's crashing your software. > >> > >> "Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message > >> news:9B3538DC-5FD1-4DE5-8890-5288CB1691F7[ at ]microsoft.com... > >> >I develop software for schools. The system is quite an extensive > >> >database. > >> > It contains over 100 forms with an average of about 8 printed pages of > >> > coding > >> > per form. I distribute the software with a runtime version of > >> > Microsoft > >> > Access 2000. > >> > > >> > With all these forms and coding, I'm being haunted my minor bugs that > >> > keep > >> > popping up now and then that close down the database, so the users have > >> > to > >> > restart the system. > >> > > >> > I keep fixing the bugs one by one, but it seems like a never ending > >> > project. > >> > Most of the bugs are initiated by students interactively doing things I > >> > never imagined they could do. > >> > > >> > My question is if I just put in the statement "End Sub" in the > >> > Err_XXXX: > >> > subroutines instead of the message statement will that prevent a minor > >> > error > >> > from shutting down the system. Is there anything else I can easily do > >> > to > >> > reduce the number of terminal problems? > >> > > >> > Any help would be appreciated. Thanks > >> > > >> > -- > >> > Frank Wagner > >> > fwagner111[ at ]aol.com > >
|
|
Frank Wagner wrote:
[Quoted Text] >Thanks. I never knew what mbe meant. I tried it and it works great. > >So my plan now is to create an mbe database whenever I want to distribute a >new version, and use that with the Sage software to create distributable >software for my clients. > >I will continue development with the mbd database, and convert it to mbe >whenever I want to distribute a new verson. Allen has given me a number of >thoughts about debugging that I also hope to implement. > >Just so everyone knows, I always compile my database regularly, and also >compact and repair it before I distribute a new version.
Just to muddy the waters for you ;-)
Compiling is certainly necessary, but it is not sufficient. You still have to guarantee that all referenced libraries are the same on the compiling machine and on all the client machines. IME, different clients insisted on their own idea of the "correct" set of libraries so there was no reasonable way for my machine's libraries to match up. This led me to adopt the (questionable?) practice of taking a decompiled program to the client's and doing the final compile on site. If any client did not manage their systems well enough to at least have the same libraries on all their machines, then it was their problem.
-- Marsh MVP [MS Access]
|
|
Marshall:
That may truely muddy the waters. My clients are schools with older computer labs. Some are still using Windows 98. There is no way I can take the system and install it on the computers in the different schools. I presently am in about 25 schools, and that may grow the 100 in the next year or two. I mail out new versions yearly for them to install. In addition, the software is used in over 100 student homes with most computers now having Windows XP or Vista.
If this is not reliable, I may be best to avoid the solution.
Let me know a little bit more about the problem of libraries if you would - - and anyone else can join in if need be.
Thanks -- Frank Wagner fwagner111[ at ]aol.com
"Marshall Barton" wrote:
[Quoted Text] > Frank Wagner wrote: > >Thanks. I never knew what mbe meant. I tried it and it works great. > > > >So my plan now is to create an mbe database whenever I want to distribute a > >new version, and use that with the Sage software to create distributable > >software for my clients. > > > >I will continue development with the mbd database, and convert it to mbe > >whenever I want to distribute a new verson. Allen has given me a number of > >thoughts about debugging that I also hope to implement. > > > >Just so everyone knows, I always compile my database regularly, and also > >compact and repair it before I distribute a new version. > > > Just to muddy the waters for you ;-) > > Compiling is certainly necessary, but it is not sufficient. > You still have to guarantee that all referenced libraries > are the same on the compiling machine and on all the client > machines. IME, different clients insisted on their own idea > of the "correct" set of libraries so there was no reasonable > way for my machine's libraries to match up. This led me to > adopt the (questionable?) practice of taking a decompiled > program to the client's and doing the final compile on site. > If any client did not manage their systems well enough to at > least have the same libraries on all their machines, then it > was their problem. > > -- > Marsh > MVP [MS Access] >
|
|
=?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> wrote in news:0383FD69-EC4E-4035-B6C0-06BD589EA2E3[ at ]microsoft.com:
[Quoted Text] > Mike:
Eh? I think *I* was the one who mentioned that "rule"...
> Thanks for the rule on dependencies. It makes sense to me and > I'll try to use it.
Well, the key problem is determining what an outside dependency is. In general, a subroutine with strongly typed parameters that has no calls to any other code is going to be safe. And if it calls code that has error handlers, that's safe without an error handler, too.
Anything that uses object variables, whether late or early binding, needs to have an error handler, seems to me, since that is what I'd define as an outside dependency.
But something like a command button that closes a form doesn't really need an error handler, seems to me. Well, that all depends -- if you have a Me.Dirty = False in your close code, then you probably ought to have an error handler, since saving the record is the kind of thing that can very easily flush out an error that needs to be handled. An unhandled error in a record save could very easily result in losing data, while with an error handler, you can return to the record and correct the problem.
This is one reason why I'm tending towards using a subroutine like this to close forms:
Public Sub CloseForm(frm As Form, Optional intSaveType = acSaveNo) On Error GoTo errHandler If Len(frm.RecordSource & vbNullString) > 0 Then frm.Filter = vbNullString frm.FilterOn = False frm.OrderBy = vbNullString frm.OrderByOn = False If frm.Dirty Then frm.Dirty = False End If DoCmd.Close acForm, frm.Name, intSaveType
exitRoutine: Exit Sub
errHandler: MsgBox err.Number & ": " & err.Description, vbExclamation, _ "Error in CloseForm()" Resume exitRoutine End Sub
It's probably overkill for most circumstances, but it means you can call it with a command button and not worry about having an error handler in the command button's code.
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
=?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> wrote in news:2DFC4127-B0B8-43A9-BB64-E5CE8CB4FFA7[ at ]microsoft.com:
[Quoted Text] > Two > common errors that I encounter are "Invalid use of null" and > "Can't move focus to control A".
Those kinds of errors are problems in your code, and you should revise your code so that it handles Nulls (usually by testing if whatever it is IsNull() before trying to operate on it), and that you check before moving the focus to a control that can't get focus.
Error handlers should be included for things you *haven't* foreseen, and the possibility of Nulls and attempting to move focus are both things you can test for an avoid. It's always better to *avoid* an error than it is to let the error handler trap for it, partly because there's sometimes no good fallback at the time the error is raised. Or, worse yet, trying to fix the problem after you've encountered the error makes for really complicated spaghetti code.
For instance:
Sub MyControl_AfterUpdate() Me!MyControl = UCase(Me!MyControl) End Sub
Now, you could write an error handler that would recover from the condition where the user deletes the value in the control.
Or, you could just use what some developers call a "guard clause" that aborts the action if certain conditions are not met:
Sub MyControl_AfterUpdate() If IsNull(Me!MyControl) Then Exit Sub Me!MyControl = UCase(Me!MyControl) End Sub
Some people prefer this:
Sub MyControl_AfterUpdate() If Not IsNull(Me!MyControl) Then Me!MyControl = UCase(Me!MyControl) End If End Sub
But that can get really messy if the code *after* the guard clause is quite complex in and of itself. For simple code like the above, avoiding the Exit Sub is easy. But for code like this:
If ... Then Select Case ... Case 1 Case 2 Case 3 End Select Else For Each ... In ,.. ... Next ... End If
It's simpler to stick the guard clause and an Exit Sub at the top of that:
If [guard condition not met] Then Exit Sub If ... Then Select Case ... Case 1 Case 2 Case 3 End Select Else For Each ... In ,.. ... Next ... End If
than it is to incorporate the guard clause test into the If/Then/Else structure of the entire code block:
If [guard condition not met] Then If ... Then Select Case ... Case 1 Case 2 Case 3 End Select Else For Each ... In ,.. ... Next ... End If End If
Now, it's also a good principle to never have more than one exit point from a subroutine, so instead of Exit Sub you can use a GoTo exitRoutine:
If [guard condition not met] Then GoTo exitRoutine If ... Then Select Case ... Case 1 Case 2 Case 3 End Select Else For Each ... In ,.. ... Next ... End If
exitRoutine: Exit Sub
If you've got an error handler, you'll already have an exit label defined, so a pretty good principle is that it you already *have* an exit point defined, use it instead of Exit Sub. If you don't, then you have to decide if your code is sufficiently complex to add in the exit point, but if your code is complex enough to ask that question, it's probably complex enough that it should have an error handler.
More than you ever wanted to know!
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
Frank Wagner wrote:
[Quoted Text] >That may truely muddy the waters. My clients are schools with older >computer labs. Some are still using Windows 98. There is no way I can take >the system and install it on the computers in the different schools. I >presently am in about 25 schools, and that may grow the 100 in the next year >or two. I mail out new versions yearly for them to install. In addition, >the software is used in over 100 student homes with most computers now having >Windows XP or Vista. > >If this is not reliable, I may be best to avoid the solution. > >Let me know a little bit more about the problem of libraries if you would - >- and anyone else can join in if need be.
You may(?) be relatively safe if the only libraries you use are the standard VBA, Access and DAO libraries, which should be installed as part of the runtime Access. Things might get tricky if a user installs their own version of Access in the same directory as your runtime or vice versa, they also use A2007 (not likely on machines older than Win XP), or if you use other libraries that can be superseded by other user installed software. There are some Access SPs and SRs that can also require a Decompile/Compile.
This issue is not related to your solution. In fact, I believe, using the runtime helps minimize the problem. I am certain that others have more experience distributing an application as widely as you are trying to do, so it would be nice if they would help clarify things.
-- Marsh MVP [MS Access]
|
|
=?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> wrote in news:AAF4C90D-2A65-491E-B8E1-DD4A93E5D8A0[ at ]microsoft.com:
[Quoted Text] > One problem that haunts me is when a > student enters the wrong answer, the focus doesn't want to return > to the same answer control even if I instruct it to with the "Set > Focus" command. I have to jump through hoops to get it back to > the same spot.
If you want to prevent leaving the control when something invalid is entered, you should be validating the data entered in control's BeforeUpdate event. You would then use the control's .Text property, which is at that point distinct from the value in the underlying bound field (because the BeforeUpdate event runs *before* the underlying bound field is actually updated).
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
Marshall Barton <marshbarton[ at ]wowway.com> wrote in news:pqmak417rjsmgshrr2bgeqkas5f6spadua[ at ]4ax.com:
[Quoted Text] > Compiling is certainly necessary, but it is not sufficient. > You still have to guarantee that all referenced libraries > are the same on the compiling machine and on all the client > machines. IME, different clients insisted on their own idea > of the "correct" set of libraries so there was no reasonable > way for my machine's libraries to match up. This led me to > adopt the (questionable?) practice of taking a decompiled > program to the client's and doing the final compile on site. > If any client did not manage their systems well enough to at > least have the same libraries on all their machines, then it > was their problem.
I think that you really oughtn't need to do that if you use late binding for everything but the default Access libraries. The only thing that would then cause it to fail would be something like the DAO DLL not being registered, and compiling on that machine wouldn't fix that, in any case.
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
=?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> wrote in news:653C79DA-8D87-4A49-91E2-C61F58C9C21F[ at ]microsoft.com:
[Quoted Text] > Let me know a little bit more about the problem of libraries if > you would - - and anyone else can join in if need be.
If you're distributing on Win9x, then you're obviously using A2K or earlier. The key thing about MDEs failing is the question of references, which can't be fixed up on the fly in an MDE. Because of this, as I said in my reply to Marsh's post, I use late binding for everything but the default Access references. This means that the only references any of my Access databases have in them are:
Visual Basic for Applications Microsoft Access X.X Object Library Microsoft DAO X.X Object Library
In the case of Access 2007, the DAO library is called something else now (ACE?), and the X.X will differ according to the version of Access, e.g., for A2K, it's Access 9 and DAO 3.6, for A2K, Access 10 and DAO 3.6 and for A2K3, Access 11 and DAO 3.6 (noticing a pattern?). Any other libraries, such as the Office Automation library or JRO or any of a number of others I get rid of the reference and use late binding.
Late binding means that your code doesn't have any compilation dependencies on that outside libary that you're using through late binding. It also means it's possible to recover from the absence (or misconfiguration) of the outside component.
Search the Access newsgroups on Google Groups for the phrase "late binding" for lots and lots of posts on the subject. It's a tool that anyone distributing a runtime app really needs to use regularly, particularly given diverse target systems.
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
David and Marshall:
I use Access 2000, and all the code is ADO. I have not made any library references except what comes standard with Access 2000. Does that help any? -- Frank Wagner fwagner111[ at ]aol.com
"David W. Fenton" wrote:
[Quoted Text] > =?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> > wrote in news:653C79DA-8D87-4A49-91E2-C61F58C9C21F[ at ]microsoft.com: > > > Let me know a little bit more about the problem of libraries if > > you would - - and anyone else can join in if need be. > > If you're distributing on Win9x, then you're obviously using A2K or > earlier. The key thing about MDEs failing is the question of > references, which can't be fixed up on the fly in an MDE. Because of > this, as I said in my reply to Marsh's post, I use late binding for > everything but the default Access references. This means that the > only references any of my Access databases have in them are: > > Visual Basic for Applications > Microsoft Access X.X Object Library > Microsoft DAO X.X Object Library > > In the case of Access 2007, the DAO library is called something else > now (ACE?), and the X.X will differ according to the version of > Access, e.g., for A2K, it's Access 9 and DAO 3.6, for A2K, Access 10 > and DAO 3.6 and for A2K3, Access 11 and DAO 3.6 (noticing a > pattern?). Any other libraries, such as the Office Automation > library or JRO or any of a number of others I get rid of the > reference and use late binding. > > Late binding means that your code doesn't have any compilation > dependencies on that outside libary that you're using through late > binding. It also means it's possible to recover from the absence (or > misconfiguration) of the outside component. > > Search the Access newsgroups on Google Groups for the phrase "late > binding" for lots and lots of posts on the subject. It's a tool that > anyone distributing a runtime app really needs to use regularly, > particularly given diverse target systems. > > -- > David W. Fenton http://www.dfenton.com/ > usenet at dfenton dot com http://www.dfenton.com/DFA/>
|
|
Marshall:
See my response to David. Does this help? -- Frank Wagner fwagner111[ at ]aol.com
"Marshall Barton" wrote:
[Quoted Text] > Frank Wagner wrote: > >That may truely muddy the waters. My clients are schools with older > >computer labs. Some are still using Windows 98. There is no way I can take > >the system and install it on the computers in the different schools. I > >presently am in about 25 schools, and that may grow the 100 in the next year > >or two. I mail out new versions yearly for them to install. In addition, > >the software is used in over 100 student homes with most computers now having > >Windows XP or Vista. > > > >If this is not reliable, I may be best to avoid the solution. > > > >Let me know a little bit more about the problem of libraries if you would - > >- and anyone else can join in if need be. > > > You may(?) be relatively safe if the only libraries you use > are the standard VBA, Access and DAO libraries, which should > be installed as part of the runtime Access. Things might get > tricky if a user installs their own version of Access in the > same directory as your runtime or vice versa, they also use > A2007 (not likely on machines older than Win XP), or if you > use other libraries that can be superseded by other user > installed software. There are some Access SPs and SRs that > can also require a Decompile/Compile. > > This issue is not related to your solution. In fact, I > believe, using the runtime helps minimize the problem. I am > certain that others have more experience distributing an > application as widely as you are trying to do, so it would > be nice if they would help clarify things. > > -- > Marsh > MVP [MS Access] >
|
|
Responses in-line.
"Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message news:AAF4C90D-2A65-491E-B8E1-DD4A93E5D8A0[ at ]microsoft.com...
[Quoted Text] > I understand you comments about error handling, and will be working on > making sure errors are logged as a part of the system. Thanks for leading > me to the code for doing that. One question I had is how do you capture > the name of the calling procedure?
Unfortunately, VBA does not expose the name of the currently-executing procedure.
MZTools will drop the proc. name in for you. For a place-holder, use: {PROCEDURE_NAME}
The other piece of the puzzle is the module name. Module.Name fails in an MDE. Me.Name doesn't work for stand-alone modules. What I do is to declare a private constant of the same name in the General Declaration section of every module, e.g.: Private Const conMod = "Module1" I can then use conMod in the code that calls the generic error handler, so it receives the name of the relevant module. And if you cut/copy'n'paste to another module, there's nothing to change (i.e. it still reports the correct module.) So, the error handler template I use in MZTools is:
'On Error GoTo Err_Handler 'Purpose: {PROCEDURE_BODY}
Exit_Handler: Exit {PROCEDURE_TYPE}
Err_Handler: Call LogError(Err.Number, Err.Description, conMod & ".{PROCEDURE_NAME}") Resume Exit_Handler
(Note that this inserts the error handler commented out until I get the procedure debugged.)
> Focus control is one thing that drives me crazy. Do you know of any good > source of information for me to study? One problem that haunts me is when > a student enters the wrong answer, the focus doesn't want to return to the > same answer control even if I instruct it to with the "Set Focus" command. > I have to jump through hoops to get it back to the same spot.
David Fenton's reply explains how cancelling the control's BeforeUpdate event keeps focus there until you get a valid entry. That's the best approach.
Having said that, this is something I use only rarely. Mostly, I prefer to do all the validation in Form_BeforeUpdate. I think people find it less annoying if they get the chance to fix a silly thing themselves, and only handle one message box if things are not right. (Additionally, Form_BeforeUpdate is the only event to compare fields, and to test for nulls.)
> By the way, my daughter attended the University of Notre Dame branch > in Perth a number of years ago. She loved the area. It's beautiful.
Wow. Yes, it's a very enjoyable city. Thanks.
-- 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.
|
|
David:
Since I only use the default libraries does that mean that late binding is not necessary?
If it is necessary, I'm afraid you'll have to explain it to me a little more. If that means compiling on the clients site, I'm afraid that wouldn't work in my case.
Thanks -- Frank Wagner fwagner111[ at ]aol.com
"David W. Fenton" wrote:
[Quoted Text] > Marshall Barton <marshbarton[ at ]wowway.com> wrote in > news:pqmak417rjsmgshrr2bgeqkas5f6spadua[ at ]4ax.com: > > > Compiling is certainly necessary, but it is not sufficient. > > You still have to guarantee that all referenced libraries > > are the same on the compiling machine and on all the client > > machines. IME, different clients insisted on their own idea > > of the "correct" set of libraries so there was no reasonable > > way for my machine's libraries to match up. This led me to > > adopt the (questionable?) practice of taking a decompiled > > program to the client's and doing the final compile on site. > > If any client did not manage their systems well enough to at > > least have the same libraries on all their machines, then it > > was their problem. > > I think that you really oughtn't need to do that if you use late > binding for everything but the default Access libraries. The only > thing that would then cause it to fail would be something like the > DAO DLL not being registered, and compiling on that machine wouldn't > fix that, in any case. > > -- > David W. Fenton http://www.dfenton.com/ > usenet at dfenton dot com http://www.dfenton.com/DFA/>
|
|
David W. Fenton wrote:
[Quoted Text] >Marshall Barton <marshbarton[ at ]wowway.com> wrote in >news:pqmak417rjsmgshrr2bgeqkas5f6spadua[ at ]4ax.com: > >> Compiling is certainly necessary, but it is not sufficient. >> You still have to guarantee that all referenced libraries >> are the same on the compiling machine and on all the client >> machines. IME, different clients insisted on their own idea >> of the "correct" set of libraries so there was no reasonable >> way for my machine's libraries to match up. This led me to >> adopt the (questionable?) practice of taking a decompiled >> program to the client's and doing the final compile on site. >> If any client did not manage their systems well enough to at >> least have the same libraries on all their machines, then it >> was their problem. > >I think that you really oughtn't need to do that if you use late >binding for everything but the default Access libraries. The only >thing that would then cause it to fail would be something like the >DAO DLL not being registered, and compiling on that machine wouldn't >fix that, in any case.
Good to hear that from someone with your experience, David. Thanks for clarifying the runtime scenario.
-- Marsh MVP [MS Access]
|
|
Albert:
Thanks to you and everyone else who has helped me. I think I've got a direction now that I can proceed with.
Thanks Again -- Frank Wagner fwagner111[ at ]aol.com
"Albert D. Kallal" wrote:
[Quoted Text] > Well, if you always distribute a mde, then un-handled errors don't shut > down access, and you do not loose any local or global vars. > > Remember, one un-handled error and ALL LOCAL + GLOBAL vars will be lost. > This means you application can become quite un-reliable unless EVERY routine > has error handling. > > However, while you could put error handling in every singe routine, why not > just use > a mde? Keep in mind that a mde NEVER looses it variables even with NO error > handling > and a error occurs. This just results in a far more reliable application. > > And, using a mde also means that access does not shut down either. I never > used the 2000 runtime, but I used 2003 and 2007. In these cases a mde (or > accde) that has a runtime error does NOT force the application to shut down. > I don't believe that the 2000 runtime is any different here. > > While I do suggest that you have good error handling, I am of the view that > one does not need to have error handling absolute every routine, especially > when you use a mde. > > So, if you are not using a mde, that would likely the best step you could > take to > improve reliability. And, a mde is smaller, and runs faster, and it can't > become un-compiled which will reduce bloat. > > > -- > Albert D. Kallal (Access MVP) > Edmonton, Alberta Canada > pleaseNOOSpamKallal[ at ]msn.com > > > >
|
|
Marshall:
Thanks to you and everyone else who has helped me. I think I've got a direction now that I can proceed with.
Thanks Again -- Frank Wagner fwagner111[ at ]aol.com
-- Frank Wagner fwagner111[ at ]aol.com
"Marshall Barton" wrote:
[Quoted Text] > Frank Wagner wrote: > >Thanks. I never knew what mbe meant. I tried it and it works great. > > > >So my plan now is to create an mbe database whenever I want to distribute a > >new version, and use that with the Sage software to create distributable > >software for my clients. > > > >I will continue development with the mbd database, and convert it to mbe > >whenever I want to distribute a new verson. Allen has given me a number of > >thoughts about debugging that I also hope to implement. > > > >Just so everyone knows, I always compile my database regularly, and also > >compact and repair it before I distribute a new version. > > > Just to muddy the waters for you ;-) > > Compiling is certainly necessary, but it is not sufficient. > You still have to guarantee that all referenced libraries > are the same on the compiling machine and on all the client > machines. IME, different clients insisted on their own idea > of the "correct" set of libraries so there was no reasonable > way for my machine's libraries to match up. This led me to > adopt the (questionable?) practice of taking a decompiled > program to the client's and doing the final compile on site. > If any client did not manage their systems well enough to at > least have the same libraries on all their machines, then it > was their problem. > > -- > Marsh > MVP [MS Access] >
|
|
David:
Thanks to you and everyone else who has helped me. I think I've got a direction now that I can proceed with.
Thanks Again -- Frank Wagner fwagner111[ at ]aol.com
-- Frank Wagner fwagner111[ at ]aol.com
"David W. Fenton" wrote:
[Quoted Text] > =?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> > wrote in news:653C79DA-8D87-4A49-91E2-C61F58C9C21F[ at ]microsoft.com: > > > Let me know a little bit more about the problem of libraries if > > you would - - and anyone else can join in if need be. > > If you're distributing on Win9x, then you're obviously using A2K or > earlier. The key thing about MDEs failing is the question of > references, which can't be fixed up on the fly in an MDE. Because of > this, as I said in my reply to Marsh's post, I use late binding for > everything but the default Access references. This means that the > only references any of my Access databases have in them are: > > Visual Basic for Applications > Microsoft Access X.X Object Library > Microsoft DAO X.X Object Library > > In the case of Access 2007, the DAO library is called something else > now (ACE?), and the X.X will differ according to the version of > Access, e.g., for A2K, it's Access 9 and DAO 3.6, for A2K, Access 10 > and DAO 3.6 and for A2K3, Access 11 and DAO 3.6 (noticing a > pattern?). Any other libraries, such as the Office Automation > library or JRO or any of a number of others I get rid of the > reference and use late binding. > > Late binding means that your code doesn't have any compilation > dependencies on that outside libary that you're using through late > binding. It also means it's possible to recover from the absence (or > misconfiguration) of the outside component. > > Search the Access newsgroups on Google Groups for the phrase "late > binding" for lots and lots of posts on the subject. It's a tool that > anyone distributing a runtime app really needs to use regularly, > particularly given diverse target systems. > > -- > David W. Fenton http://www.dfenton.com/ > usenet at dfenton dot com http://www.dfenton.com/DFA/>
|
|
Allen:
Thanks to you and everyone else who has helped me. I think I've got a direction now that I can proceed with.
Thanks Again -- Frank Wagner fwagner111[ at ]aol.com
"Allen Browne" wrote:
[Quoted Text] > Responses in-line. > > "Frank Wagner" <FrankWagner[ at ]discussions.microsoft.com> wrote in message > news:AAF4C90D-2A65-491E-B8E1-DD4A93E5D8A0[ at ]microsoft.com... > > I understand you comments about error handling, and will be working on > > making sure errors are logged as a part of the system. Thanks for leading > > me to the code for doing that. One question I had is how do you capture > > the name of the calling procedure? > > Unfortunately, VBA does not expose the name of the currently-executing > procedure. > > MZTools will drop the proc. name in for you. > For a place-holder, use: > {PROCEDURE_NAME} > > The other piece of the puzzle is the module name. Module.Name fails in an > MDE. Me.Name doesn't work for stand-alone modules. What I do is to declare a > private constant of the same name in the General Declaration section of > every module, e.g.: > Private Const conMod = "Module1" > I can then use conMod in the code that calls the generic error handler, so > it receives the name of the relevant module. And if you cut/copy'n'paste to > another module, there's nothing to change (i.e. it still reports the correct > module.) So, the error handler template I use in MZTools is: > > 'On Error GoTo Err_Handler > 'Purpose: > {PROCEDURE_BODY} > > Exit_Handler: > Exit {PROCEDURE_TYPE} > > Err_Handler: > Call LogError(Err.Number, Err.Description, conMod & ".{PROCEDURE_NAME}") > Resume Exit_Handler > > (Note that this inserts the error handler commented out until I get the > procedure debugged.) > > > Focus control is one thing that drives me crazy. Do you know of any good > > source of information for me to study? One problem that haunts me is when > > a student enters the wrong answer, the focus doesn't want to return to the > > same answer control even if I instruct it to with the "Set Focus" command. > > I have to jump through hoops to get it back to the same spot. > > David Fenton's reply explains how cancelling the control's BeforeUpdate > event keeps focus there until you get a valid entry. That's the best > approach. > > Having said that, this is something I use only rarely. Mostly, I prefer to > do all the validation in Form_BeforeUpdate. I think people find it less > annoying if they get the chance to fix a silly thing themselves, and only > handle one message box if things are not right. (Additionally, > Form_BeforeUpdate is the only event to compare fields, and to test for > nulls.) > > > By the way, my daughter attended the University of Notre Dame branch > > in Perth a number of years ago. She loved the area. It's beautiful. > > Wow. Yes, it's a very enjoyable city. Thanks. > > -- > 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. > >
|
|
=?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> wrote in news:30EF2A9D-F1F3-4827-A2EE-B6559559EA08[ at ]microsoft.com:
[Quoted Text] > Since I only use the default libraries does that mean that late > binding is not necessary?
Depends on what you mean by "default libraries." I often see Access add in an Office Automation library and compatibility libraries when I upgrade, and these are completely unnecessary to any of my apps. As I said in my other post, the three base references are all I ever have in any of my apps. Any other library that I use, I use via late binding, with no reference.
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
=?Utf-8?B?RnJhbmsgV2FnbmVy?= <FrankWagner[ at ]discussions.microsoft.com> wrote in news:B5F3C770-AF2E-4EFD-880B-A04FD1AE7217[ at ]microsoft.com:
[Quoted Text] > I use Access 2000, and all the code is ADO. I have not made any > library references except what comes standard with Access 2000. > Does that help any?
Well, right away I see a problem in using ADO, which is not something I consider to be native Access. If your back end is SQL Server, perhaps it makes sense, but if it's Jet, then using ADO is really not justifiable in any way, in my opinion. MS wanted you to *think* you should use ADO with Jet, but they were mistaken -- it was always a silly idea.
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
"Allen Browne" <AllenBrowne[ at ]SeeSig.Invalid> wrote in news:umnp36lXJHA.1188[ at ]TK2MSFTNGP05.phx.gbl:
in re: control's BeforeUpdate event
[Quoted Text] > Having said that, this is something I use only rarely. Mostly, I > prefer to do all the validation in Form_BeforeUpdate. I think > people find it less annoying if they get the chance to fix a silly > thing themselves, and only handle one message box if things are > not right. (Additionally, Form_BeforeUpdate is the only event to > compare fields, and to test for nulls.)
I think it makes sense to validate entry when it's happening. That means choosing an appropriate control type in the first place. If a field can only have a limited number of values, an option group or a combo box or listbox are the appropriate control type.
If it's a date field, Access date handling will prevent the entry of an invalid date, but it won't prevent you from entering nonsensical dates (such as 12/15/208 instead of 12/15/2008). For that, you can use an input mask or logic in the BeforeUpdate event. I have something of a love-hate relationship with input masks -- I hate them myself, but users don't seem to mind them at all, since they take away any need for them to think about what they are supposed to enter.
I wouldn't leave something like that to a form-level event. Indeed, I wouldn't leave cross-field comparisons to a form-level event, because I think it's extraordinarily annoying to enter a bunch of data and then after your focus has moved on from entering each piece of information, to be informed of an error in the data. Say you're entering data from a paper form. If you get the validation message at the time you enter one piece of data, you should immediately be able to scan back to the exact same location on the paper form to check what you should have typed. If the validation is left to the end, you have to rescan the whole page and relocate each individual piece of data.
I can see situations where groups of fields should definitely be validated together, but in that case, I'd like use a wizard-type interface, with data fields entered in small groups, with <<Previous and Next>> buttons, and the Next>> button would not be enabled until the data in the current set of fields is valid and internallly consistent.
-- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/
|
|
|