Force a save

M

Marshall Barton

Stuart said:
"Marshall Barton" wrote [snip]
Getting code to execute properly is only half the battle. Maintainability
later is the other half.

I agree. Getting it to work the first time is relatively
easy compared to keeping it working under a shower of
changes over a long period of time. {war story: I worked
for over three years creating a massive program in the late
'60s. In '98, eight years after I retired, they called me
to convert it from IBM360 assembly to C. How it made it
that long with who knows how many programmers says something
about maintainability, but there was no way I was going to
get involved with that monster again.}
If I use:

If Me.Dirty Then Me.Dirty = False

I am compelled to add the comment "If record changed, save it" (but maybe
that's just me).

I can't disagree with your compulsion ;-)
As Dijkstra said, "The tools we use have a profound (and devious!) influence
on our thinking habits, and therefore, on our thinking abilities."

He was a wise man. OTOH, after using my first dozen
programming languages (and creating several more), I feel
moderately eclectic about software development ;-),
 
R

Rick Brandt

Stuart said:
One last thing, regarding your earlier comment about code
readability, it seems a shame that RunCommand acCmdSaveRecord is
being deprecated. It's self-commenting code, and again if Access
already knows there have been no changes, it could just be ignored.
That's the behaviour I'd like to see anyway.

My opinion only, but if some future developer is working on your code and is
confused by Me.Dirty = False then he's pretty much going to butcher the project
anyway.

If you really want functions to be more self documenting then create a library
module with wrappers using your own names...

Function SaveRecord(frm As Form)
If frm.Dirty Then frm.Dirty = False
End Function

(usage)
SaveRecord(Me)

This also allows you to provide more explicit error handling and error messages
than you get from Access.
 
R

Rick Brandt

Marshall said:
The BIG problem with the RunCommand (and many other DoCmd
methods) is that you can not specify which object you want
it to operate on. Impatient users randomly clicking and
Timer event are notorious for changing the current object
out from under your code.

Not to mention that many don't work when stepping through code. acCmdSaveRecord
being a prime example.
 
S

Stuart McCall

Marshall Barton said:
Stuart said:
"Marshall Barton" wrote [snip]
Getting code to execute properly is only half the battle. Maintainability
later is the other half.

I agree. Getting it to work the first time is relatively
easy compared to keeping it working under a shower of
changes over a long period of time. {war story: I worked
for over three years creating a massive program in the late
'60s. In '98, eight years after I retired, they called me
to convert it from IBM360 assembly to C. How it made it
that long with who knows how many programmers says something
about maintainability, but there was no way I was going to
get involved with that monster again.}
If I use:

If Me.Dirty Then Me.Dirty = False

I am compelled to add the comment "If record changed, save it" (but maybe
that's just me).

I can't disagree with your compulsion ;-)
As Dijkstra said, "The tools we use have a profound (and devious!)
influence
on our thinking habits, and therefore, on our thinking abilities."

He was a wise man. OTOH, after using my first dozen
programming languages (and creating several more), I feel
moderately eclectic about software development ;-),

So you retired in 1990? Wow, and here's me declaring myself to be long in
the tooth lol. I come from a hobbyist background, started around '78 or so.
I first played around with Z80 assembler, making extensions for Quick Basic,
then I've stuck with Basic ever since. Actually I was doing more hardware
than software in those days, but when Access came along, I just couldn't
resist, especially seeing as I was perfectly placed to create systems for
small local businesses. Since then my world has never been the same :)
 
S

Stuart McCall

Rick Brandt said:
My opinion only, but if some future developer is working on your code and
is confused by Me.Dirty = False then he's pretty much going to butcher the
project anyway.

Lol! Good point, and too true.
If you really want functions to be more self documenting then create a
library module with wrappers using your own names...

Function SaveRecord(frm As Form)
If frm.Dirty Then frm.Dirty = False
End Function

(usage)
SaveRecord(Me)

Funnily enough, that almost matches a function in my lib:

Public Function RecordSave() As Long
Screen.ActiveForm.Dirty = False
End Function

I use Screen.ActiveForm because I know darn well its being called from the
correct form.
Of course I'll be modifying it following this exchange, probably to:

With Screen.ActiveForm
If .Dirty Then .Dirty = False
End With
This also allows you to provide more explicit error handling and error
messages than you get from Access.

Of course, and I take your point re single stepping and RunCommand,
mentioned elsewhere. Hadn't thought of that (don't think I've run into it
actually)
 
R

Rick Brandt

Stuart said:
Funnily enough, that almost matches a function in my lib:

Public Function RecordSave() As Long
Screen.ActiveForm.Dirty = False
End Function

I use Screen.ActiveForm because I know darn well its being called
from the correct form.
Of course I'll be modifying it following this exchange, probably to:

Dangerous in my opinion. I have seen many occassions with dialogs and such
where the form with focus is most defnitely not the one executing the code.
It takes exactly two extra characters "Me" to pass the form to your function
so that there is no doubt at all.
 
S

Stuart McCall

Rick Brandt said:
Dangerous in my opinion. I have seen many occassions with dialogs and
such where the form with focus is most defnitely not the one executing the
code. It takes exactly two extra characters "Me" to pass the form to your
function so that there is no doubt at all.

There can be no focus problem, as the function is called from code in the
form's module. Of course this routine is from my personal lib (used for
years, never had a problem), so certain assumptions may be made. I would not
recommend this as "public" code, but probably something like your
suggestion. Dangerous I agree, in the wrong hands.
 
R

Rick Brandt

Stuart said:
There can be no focus problem, as the function is called from code in
the form's module.

Has absolutely nothing to do with it. Between the time your code starts
running and the time that the save line is encountered another object can
grab focus.
 
D

David W. Fenton

I think the only speed difference is whether the If Me.Dirty
is faster than the processing to transition to and execute
the internal code part of the Me.Dirty = False prior to the
record save, if needed. Dirk says it is slightly, but not
noticibly, faster.

I got in the habit of testing before saving back in the days when I
was doing replicated apps with Jet 3.5 because conflict resolution
in Jet 3.5 used "least decisive user" to resolve conflicts (i.e.,
the record with the most changes won). A save is a save, and saving
when it is not needed *could* have updated the s_Generation field of
the records.

Philosophically, I believe in not doing actions that are
unnecessary, and so I test. It's only in loops that the performance
hit for checking Me.Dirty would matter, and, well, how often would
you write a loop that would be processing multiple records of a form
where you wouldn't already know if the form had been changed or not?
And then, the time moving from record to record would surely be much
greater than the time to check if the record had been edited or not.

So, I see it as one of those things that isn't strictly necessary,
but does no harm.
 
D

David W. Fenton

Funnily enough, that almost matches a function in my lib:

Public Function RecordSave() As Long
Screen.ActiveForm.Dirty = False
End Function

I use Screen.ActiveForm because I know darn well its being called
from the correct form.

What if you want to save a form that's *not* the active form? Then
you have to make a different form the active form, call your save,
then set the original form back to being the active form.

It's much cleaner to explicitly pass the form reference as a
parameter, in my opinion, and makes the code much more useful.
 
S

Stuart McCall

David W. Fenton said:
What if you want to save a form that's *not* the active form? Then
you have to make a different form the active form, call your save,
then set the original form back to being the active form.

It's much cleaner to explicitly pass the form reference as a
parameter, in my opinion, and makes the code much more useful.

I have no argument with that, or indeed with anything put forward in this
thread. As I mentioned earlier, That routine is not for public consumption.
You mean you don't have any code which can make certain assumptions because
you _know_ it will be called correctly, when the circumstances are right? I
was under the impression most developers did. Of course this routine is only
a simple example, but the technique (speaking generally) can come in mighty
handy (IMHO).
 
M

Marshall Barton

Stuart said:
That was a brain fart. The language was Sinclair Basic.


No problem. I don't even try to remember what the
variations of Basic are called.
 
D

David W. Fenton

I have no argument with that, or indeed with anything put forward
in this thread. As I mentioned earlier, That routine is not for
public consumption. You mean you don't have any code which can
make certain assumptions because you _know_ it will be called
correctly, when the circumstances are right? I was under the
impression most developers did. Of course this routine is only a
simple example, but the technique (speaking generally) can come in
mighty handy (IMHO).

It depends on how hard it is to make it independent of the
assumptions. If it's as easy as passing the form reference, then I'd
*never* make the assumption about when it's going to be used. If
it's hard to make it independent of context, then I'd likely decide
how much of a difference it makes to the current client paying the
bills and how much it would cost them now vs. how much it could
possibly save them in the future.

For what it's worth, I tend to avoid ever coding things like
Screen.ActiveControl and anything that depends on using the active
form, simply because it's so hard to debug that I can never trust it
in operation. The only time I use Screen.ActiveControl is when I am
disabling controls and need to make sure I'm not trying to disable
the active control. Other than that, I don't use it at all, simply
because I don't like depending on implicit things happening at
runtime that I didn't call for explicitly.
 
M

Marshall Barton

David W. Fenton wrote:
[snip a lot of context]
The only time I use Screen.ActiveControl is when I am
disabling controls and need to make sure I'm not trying to disable
the active control.


OTOH, there should be no confusion when using
Me.ActiveControl
 
D

David W. Fenton

David W. Fenton wrote:
[snip a lot of context]
The only time I use Screen.ActiveControl is when I am
disabling controls and need to make sure I'm not trying to disable
the active control.

OTOH, there should be no confusion when using
Me.ActiveControl

Well, no confusion about the control's parent, but still plenty of
possibility for it not being what you expect.

I have no objection to querying information about the active control
and then taking actions on the control indicated by ,ActiveControl.
I just object to operating directly on Me.ActiveControl or
Screen.ActiveControl. I think it's important to check what is
pointed to by .ActiveCOntrol and then choose what you do, precisely
because the results can be so unexpected.
 
M

Marshall Barton

David said:
Marshall Barton said:
David W. Fenton wrote:
[snip a lot of context]
The only time I use Screen.ActiveControl is when I am
disabling controls and need to make sure I'm not trying to disable
the active control.

OTOH, there should be no confusion when using
Me.ActiveControl

Well, no confusion about the control's parent, but still plenty of
possibility for it not being what you expect.

I have no objection to querying information about the active control
and then taking actions on the control indicated by ,ActiveControl.
I just object to operating directly on Me.ActiveControl or
Screen.ActiveControl. I think it's important to check what is
pointed to by .ActiveCOntrol and then choose what you do, precisely
because the results can be so unexpected.


Sure, but my point was that the Screen object is not always
the same as the form with the running code. Checking
Screen.ActiveForm Is Me seems redundent when Me can be used
directly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top