store a calculated value

J

jlute

I have what I believe is a unique situation. I have a query with many
complex calculations that generates a value that I need in another
query. The problem is that joining the queries is just too much and I
get the dreaded "Query too complex" bomb. I've tried some things to
trim the query "fat" but it is what it is and no amount of dieting is
going to help.

I've found many posts about store calculated values and they all have
their risks and challenges however mine is risk-free. The calculated
value that I need is generated ONLY when changes are made to the query
via its form therefore storing the value in a table field *should* be
no problem-o?

Can I run an AfterUpdate event with the calculated control to populate
a field in a table? I've tried and it's not working.

Any direction you might have would be appreciated.

Thanks!
 
G

Golfinray

It is generally not a good idea to store calculations, but rather calculate
and use them as you need them. If you do need to store them, you could use a
list box with the control sourse =(calculation) and store it back to the
table.
 
J

jlute

It is generally not a good idea to store calculations, but rather calculate
and use them as you need them.

Understood however this is one of those exceptions to the rule as I
noted.
If you do need to store them, you could use a
list box with the control sourse =(calculation) and store it back to the
table.

Do you mean to create a list box that does the entire calculation...?
 
G

Golfinray

Yes, the list box can do the required calculation. If you tell us what kind
of calculation you need, we might be able to help you put that together.
 
K

Klatuu

Why is it an exception?

It is generally not a good idea to store calculations, but rather
calculate
and use them as you need them.

Understood however this is one of those exceptions to the rule as I
noted.
If you do need to store them, you could use a
list box with the control sourse =(calculation) and store it back to the
table.

Do you mean to create a list box that does the entire calculation...?
 
J

jlute

Thanks. I'm not sure I'm being clear. I simply need to "push" a
calculated value from a query into a field in a table.

As I noted the query does some complex stuff:
SELECT tblMZFAINGPhysicalAttributes.txtProfileID,
tblMZFAINGPhysicalAttributes.ServingWeight,
tblMZFAINGPhysicalAttributes.SWUOM,
tblMZFAINGPhysicalAttributes.SWComments,
tblMZFAINGPhysicalAttributes.ProcessTemp AS T, [T]*1.8+32 AS TDegF,
tblMZFAINGPhysicalAttributes.Moisture,
tblMZFAINGPhysicalAttributes.Protein,
tblMZFAINGPhysicalAttributes.Fat,
tblMZFAINGPhysicalAttributes.Carbohydrates,
tblMZFAINGPhysicalAttributes.Fiber, tblMZFAINGPhysicalAttributes.Ash,
Nz([Moisture],0)+Nz([Protein],0)+Nz([Fat],0)+Nz([Carbohydrates],
0)+Nz([Fiber],0)+Nz([Ash],0) AS CompTotal, IIf([CompTotal]="0" Or
[CompTotal]="100",Null,IIf([CompTotal]<>100,([CompTotal]-100))) AS
CompTotalDiff, [Moisture]-[CompTotalDiff] AS Moisturec,
IIf([Moisturec],[Moisturec],IIf([Moisture],[Moisture])) AS MoisturecC,
IIf(IsNull([CompTotalDiff]),Null,[Moisturec]+[Protein]+[Fat]+
[Carbohydrates]+[Fiber]+[Ash]) AS CompTotalc,
tblMZFAINGPhysicalAttributes.AppDensity, IIf([VolairVolmix]>=0,
[VolairVolmix]/([VolairVolmix]+1),Null) AS AppVoid,
([VConWms]*(2*[VConWms]+[AirCon]-2*[AppVoid]*([VConWms]-[AirCon]))/
(2*[VConWms]+[AirCon]+[AppVoid]*([VConWms]-[AirCon]))) AS PorConWmC,
[PorConWmC]/1.73073 AS PorConBTUhrftF,
0.57109+0.0017625*[T]-0.0000067036*[T]^2 AS ConMoisture,
0.17881+0.0011958*[T]-0.0000027178*[T]*[T] AS ConProtein,
0.18071+0.00027604*[T]-0.00000017749*[T]*[T] AS ConFat,
0.20141+0.0013874*[T]-0.0000043312*[T]*[T] AS ConCarb,
0.18331+0.0012497*[T]-0.0000031683*[T]*[T] AS ConFiber,
0.32962+0.0014011*[T]-0.0000029069*[T]*[T] AS ConAsh,
997.18+0.0031439*[T]-0.0037574*[T]*[T] AS DenMoisture,
1329.9-0.5184*[T] AS DenProtein, 925.59-0.41757*[T] AS DenFat,
1599.1-0.31046*[T] AS DenCarb, 1311.5-0.36589*[T] AS DenFiber,
2423.8-0.28063*[T] AS DenAsh, 4.1762-0.000090864*[T]
+0.0000054731*[T]*[T] AS HtCapMoisture,
2.0082+0.0012089*[T]-0.00000113129*[T]*[T] AS HtCapProtein,
1.9842+0.0014733*[T]-0.0000048008*[T]*[T] AS HtCapFat,
1.5488+0.0019625*[T]-0.0000059399*[T]*[T] AS HtCapCarb,
1.8459+0.0018306*[T]-0.0000046509*[T]*[T] AS HtCapFiber,
1.0926+0.0018896*[T]-0.0000036817*[T]*[T] AS HtCapAsh, (Nz([Moisture],
[Moisturec])*[ConMoisture]+[Protein]*[ConProtein]+[Fat]*[ConFat]+
[Carbohydrates]*[ConCarb]+[Fiber]*[ConFiber]+[Ash]*[ConAsh])/100 AS
VConWms, [VConWms]/1.73073 AS VConBTUhrftF, 1/([MoisturecC]/
[DenMoisture]+[Protein]/[DenProtein]+[Fat]/[DenFat]+[Carbohydrates]/
[DenCarb]+[Fiber]/[DenFiber]+[Ash]/[DenAsh])/10 AS VDengmcc, [Vdengmcc]
+8.3454044518 AS VDenlbgalgmcc, [Vdengmcc]*62.427960576 AS VDenlbcuft,
[VDenlbcuft]*0.13368055555 AS VDenlbgalcuft, (Nz([Moisture],
[Moisturec])*[HtCapMoisture]+[Protein]*[HtCapProtein]+[Fat]*[HtCapFat]+
[Carbohydrates]*[HtCapCarb]+[Fiber]*[HtCapFiber]+[Ash]*[HtCapAsh])/100
AS VHtCapkJkgC, [VHtCapkJkgC]/4.1868 AS VHtCapBTUlbF,
1.73073*(0.014+(0.0183-0.014)/100*[T]) AS AirCon, IIf(Nz([AppDensity],
0)<>0,[VDengmcc]/[AppDensity]-1,Null) AS VolairVolmix,
tblMZFAINGPhysicalAttributes.Comments
FROM tblMZFAINGPhysicalAttributes
ORDER BY tblMZFAINGPhysicalAttributes.txtProfileID;

The value that I need to store in my table is calculated in the
VDenlbgalcuft field.
 
J

jlute

Hi, David.

Because as I noted I need the calculated value in another query but
joining the queries results in "Query too complex."

I figured considering the currnet design that storing the value was
the simplest, safest resolution.
 
J

jlute

I figured out a solution throgh tinkering around. I put together an
AfterUpdate event for the subform:

Private Sub Form_AfterUpdate()

Forms![frmMZFormulas]![sfrmMZFAPhysicalAttributes].Form!
[CalcDensitylbgal] = Forms![frmMZFormulas]!
[sfrmMZFAPhysicalAttributes]![sfrmMZFAPhysicalAtts].Form!
[numVDenlbgalcuft]

End Sub

This does the trick. The only hiccup is that the "pushed" value
doesn't appear until after exiting sfrmMZFAPhysicalAtts - of course.
If anyone could tell me how to save the subform record and then
requery sfrmMZFAPhysicalAttributes I'd be a very happy camper!
 
K

Ken Sheridan

What is the column on which the value of the VDenlbgalcuft column will be
functionally dependent in the table into which you wish to insert the values?
I'm guessing that txtProfileID is the key of the
tblMZFAINGPhysicalAttributes table on which your current query is based, so
will this also be the column in the 'target' table which will functionally
determine the value of the VDenlbgalcuft column?

If so I'd suggest that you insert distinct values of the two columns into a
pre-designed 2-column temporary table which you can then join this to the
'target' table in the final query. So the process would be to first delete
all rows from the temporary table, then insert the new rows, then finally
open the query, or a report/form based on it. This could be automated in VBA
along these lines, for which I've assumed the end product is a report in
print preview:

Dim cmd As ADODB.Command
Dim strSQL As String

Set cmd = New ADODB.Command
cmd.ActiveConnection = CurrentProject.Connection
cmd.CommandType = adCmdText

'empty temporary table
strSQL = "DELETE * FROM tblTemp"
cmd.CommandText = strSQL
cmd.Execute

' insert rows into temporary table
strSQL = "INSERT INTO tblTemp(txtProfileID, VDenlbgalcuft) " & _
"SELECT DISTINCT txtProfileID, VDenlbgalcuft " & _
"FROM YourCurrentQuery"
cmd.CommandText = strSQL
cmd.Execute

' open a report based on a query which joins tblTemp
' to other table(s) on txtProfileID columns
DoCmd.OpenReport "YourReportName", View:=acViewPreview

Using this approach the computed VDenlbgalcuft values are isolated from the
main working tables by being held temporarily in tblTemp, which to some
degree mitigates the potential risk of inconsistency which arises from
introducing the redundancy.

Ken Sheridan
Stafford, England

Thanks. I'm not sure I'm being clear. I simply need to "push" a
calculated value from a query into a field in a table.

As I noted the query does some complex stuff:
SELECT tblMZFAINGPhysicalAttributes.txtProfileID,
tblMZFAINGPhysicalAttributes.ServingWeight,
tblMZFAINGPhysicalAttributes.SWUOM,
tblMZFAINGPhysicalAttributes.SWComments,
tblMZFAINGPhysicalAttributes.ProcessTemp AS T, [T]*1.8+32 AS TDegF,
tblMZFAINGPhysicalAttributes.Moisture,
tblMZFAINGPhysicalAttributes.Protein,
tblMZFAINGPhysicalAttributes.Fat,
tblMZFAINGPhysicalAttributes.Carbohydrates,
tblMZFAINGPhysicalAttributes.Fiber, tblMZFAINGPhysicalAttributes.Ash,
Nz([Moisture],0)+Nz([Protein],0)+Nz([Fat],0)+Nz([Carbohydrates],
0)+Nz([Fiber],0)+Nz([Ash],0) AS CompTotal, IIf([CompTotal]="0" Or
[CompTotal]="100",Null,IIf([CompTotal]<>100,([CompTotal]-100))) AS
CompTotalDiff, [Moisture]-[CompTotalDiff] AS Moisturec,
IIf([Moisturec],[Moisturec],IIf([Moisture],[Moisture])) AS MoisturecC,
IIf(IsNull([CompTotalDiff]),Null,[Moisturec]+[Protein]+[Fat]+
[Carbohydrates]+[Fiber]+[Ash]) AS CompTotalc,
tblMZFAINGPhysicalAttributes.AppDensity, IIf([VolairVolmix]>=0,
[VolairVolmix]/([VolairVolmix]+1),Null) AS AppVoid,
([VConWms]*(2*[VConWms]+[AirCon]-2*[AppVoid]*([VConWms]-[AirCon]))/
(2*[VConWms]+[AirCon]+[AppVoid]*([VConWms]-[AirCon]))) AS PorConWmC,
[PorConWmC]/1.73073 AS PorConBTUhrftF,
0.57109+0.0017625*[T]-0.0000067036*[T]^2 AS ConMoisture,
0.17881+0.0011958*[T]-0.0000027178*[T]*[T] AS ConProtein,
0.18071+0.00027604*[T]-0.00000017749*[T]*[T] AS ConFat,
0.20141+0.0013874*[T]-0.0000043312*[T]*[T] AS ConCarb,
0.18331+0.0012497*[T]-0.0000031683*[T]*[T] AS ConFiber,
0.32962+0.0014011*[T]-0.0000029069*[T]*[T] AS ConAsh,
997.18+0.0031439*[T]-0.0037574*[T]*[T] AS DenMoisture,
1329.9-0.5184*[T] AS DenProtein, 925.59-0.41757*[T] AS DenFat,
1599.1-0.31046*[T] AS DenCarb, 1311.5-0.36589*[T] AS DenFiber,
2423.8-0.28063*[T] AS DenAsh, 4.1762-0.000090864*[T]
+0.0000054731*[T]*[T] AS HtCapMoisture,
2.0082+0.0012089*[T]-0.00000113129*[T]*[T] AS HtCapProtein,
1.9842+0.0014733*[T]-0.0000048008*[T]*[T] AS HtCapFat,
1.5488+0.0019625*[T]-0.0000059399*[T]*[T] AS HtCapCarb,
1.8459+0.0018306*[T]-0.0000046509*[T]*[T] AS HtCapFiber,
1.0926+0.0018896*[T]-0.0000036817*[T]*[T] AS HtCapAsh, (Nz([Moisture],
[Moisturec])*[ConMoisture]+[Protein]*[ConProtein]+[Fat]*[ConFat]+
[Carbohydrates]*[ConCarb]+[Fiber]*[ConFiber]+[Ash]*[ConAsh])/100 AS
VConWms, [VConWms]/1.73073 AS VConBTUhrftF, 1/([MoisturecC]/
[DenMoisture]+[Protein]/[DenProtein]+[Fat]/[DenFat]+[Carbohydrates]/
[DenCarb]+[Fiber]/[DenFiber]+[Ash]/[DenAsh])/10 AS VDengmcc, [Vdengmcc]
+8.3454044518 AS VDenlbgalgmcc, [Vdengmcc]*62.427960576 AS VDenlbcuft,
[VDenlbcuft]*0.13368055555 AS VDenlbgalcuft, (Nz([Moisture],
[Moisturec])*[HtCapMoisture]+[Protein]*[HtCapProtein]+[Fat]*[HtCapFat]+
[Carbohydrates]*[HtCapCarb]+[Fiber]*[HtCapFiber]+[Ash]*[HtCapAsh])/100
AS VHtCapkJkgC, [VHtCapkJkgC]/4.1868 AS VHtCapBTUlbF,
1.73073*(0.014+(0.0183-0.014)/100*[T]) AS AirCon, IIf(Nz([AppDensity],
0)<>0,[VDengmcc]/[AppDensity]-1,Null) AS VolairVolmix,
tblMZFAINGPhysicalAttributes.Comments
FROM tblMZFAINGPhysicalAttributes
ORDER BY tblMZFAINGPhysicalAttributes.txtProfileID;

The value that I need to store in my table is calculated in the
VDenlbgalcuft field.

Yes, the list box can do the required calculation. If you tell us what kind
of calculation you need, we might be able to help you put that together.








- Show quoted text -
 
J

John W. Vinson

I have what I believe is a unique situation. I have a query with many
complex calculations that generates a value that I need in another
query. The problem is that joining the queries is just too much and I
get the dreaded "Query too complex" bomb. I've tried some things to
trim the query "fat" but it is what it is and no amount of dieting is
going to help.

I've found many posts about store calculated values and they all have
their risks and challenges however mine is risk-free. The calculated
value that I need is generated ONLY when changes are made to the query
via its form therefore storing the value in a table field *should* be
no problem-o?

Can I run an AfterUpdate event with the calculated control to populate
a field in a table? I've tried and it's not working.

Not of the calculated control; an AfterUpdate event fires only when the *user*
manually enters something into a control. You'll need to push the value in
some other appropriate event: the Form's BeforeUpdate event (after any
validation code, probably) would be a safe choice, though the user would not
see the result.

The cautions about storing calculated values are well taken, but yes, there
are exceptions - and one of them is that the calculation is just too complex
or (demonstrably) too slow.
 
J

jlute

Thanks, John - and everybody else!

I've added:
Private Sub Form_AfterUpdate()
Forms![frmMZFormulas]![sfrmMZFAPhysicalAttributes].Form!
[CalcDensitylbgal] = Forms![frmMZFormulas]!
[sfrmMZFAPhysicalAttributes]![sfrmMZFAPhysicalAtts].Form!
[numVDenlbgalcuft]
End Sub

This is working fine however I'd like to refresh the parent form. How
can I write this into the AfterUpdate, too? I've tried several things
but nothing's working. The following is what I've got that at least
doesn't trigger the debugger but it doesn't refresh the form:
Forms![frmMZFormulas]![sfrmMZFAPhysicalAttributes].Form.Refresh

Thanks!
 
D

Dale Fye

You know, another thing you might want to consider is creating a function
that computes the value that you want to store. Then, you could pass the
function the appropriate parameters. This way, you could use the function in
a query, or you could call it for only a single record in the AfterUpdate of
certain fields on a form.

I think this would be far more efficient than re-running the query, and far
easier to maintain, interpret, and understand.

--
HTH
Dale

Don''t forget to rate the post if it was helpful!

email address is invalid
Please reply to newsgroup only.
 
J

jlute

Thanks, Ken! This is a rather intriguing, long-term solution that I'll
explore!

What is the column on which the value of the VDenlbgalcuft column will be
functionally dependent in the table into which you wish to insert the values?
 I'm guessing that txtProfileID is the key of the
tblMZFAINGPhysicalAttributes table on which your current query is based, so
will this also be the column in the 'target' table which will functionally
determine the value of the VDenlbgalcuft  column?

If so I'd suggest that you insert distinct values of the two columns intoa
pre-designed 2-column temporary table which you can then join this to the
'target' table in the final query.  So the process would be to first delete
all rows from the temporary table, then insert the new rows, then finally
open the query, or a report/form based on it.  This could be automated in VBA
along these lines, for which I've assumed the end product is a report in
print preview:

    Dim cmd As ADODB.Command
    Dim strSQL As String

    Set cmd = New ADODB.Command
    cmd.ActiveConnection = CurrentProject.Connection
    cmd.CommandType = adCmdText

    'empty temporary table
    strSQL = "DELETE * FROM tblTemp"
    cmd.CommandText = strSQL
    cmd.Execute

    ' insert rows into temporary table
    strSQL = "INSERT INTO tblTemp(txtProfileID, VDenlbgalcuft) " & _
        "SELECT DISTINCT txtProfileID, VDenlbgalcuft " & _
        "FROM YourCurrentQuery"
    cmd.CommandText = strSQL
    cmd.Execute

    ' open a report based on a query which joins tblTemp
    ' to other table(s) on txtProfileID columns
    DoCmd.OpenReport "YourReportName", View:=acViewPreview

Using this approach the computed VDenlbgalcuft values are isolated from the
main working tables by being held temporarily in tblTemp, which to some
degree mitigates the potential risk of inconsistency which arises from
introducing the redundancy.

Ken Sheridan
Stafford, England



Thanks. I'm not sure I'm being clear. I simply need to "push" a
calculated value from a query into a field in a table.
As I noted the query does some complex stuff:
SELECT tblMZFAINGPhysicalAttributes.txtProfileID,
tblMZFAINGPhysicalAttributes.ServingWeight,
tblMZFAINGPhysicalAttributes.SWUOM,
tblMZFAINGPhysicalAttributes.SWComments,
tblMZFAINGPhysicalAttributes.ProcessTemp AS T, [T]*1.8+32 AS TDegF,
tblMZFAINGPhysicalAttributes.Moisture,
tblMZFAINGPhysicalAttributes.Protein,
tblMZFAINGPhysicalAttributes.Fat,
tblMZFAINGPhysicalAttributes.Carbohydrates,
tblMZFAINGPhysicalAttributes.Fiber, tblMZFAINGPhysicalAttributes.Ash,
Nz([Moisture],0)+Nz([Protein],0)+Nz([Fat],0)+Nz([Carbohydrates],
0)+Nz([Fiber],0)+Nz([Ash],0) AS CompTotal, IIf([CompTotal]="0" Or
[CompTotal]="100",Null,IIf([CompTotal]<>100,([CompTotal]-100))) AS
CompTotalDiff, [Moisture]-[CompTotalDiff] AS Moisturec,
IIf([Moisturec],[Moisturec],IIf([Moisture],[Moisture])) AS MoisturecC,
IIf(IsNull([CompTotalDiff]),Null,[Moisturec]+[Protein]+[Fat]+
[Carbohydrates]+[Fiber]+[Ash]) AS CompTotalc,
tblMZFAINGPhysicalAttributes.AppDensity, IIf([VolairVolmix]>=0,
[VolairVolmix]/([VolairVolmix]+1),Null) AS AppVoid,
([VConWms]*(2*[VConWms]+[AirCon]-2*[AppVoid]*([VConWms]-[AirCon]))/
(2*[VConWms]+[AirCon]+[AppVoid]*([VConWms]-[AirCon]))) AS PorConWmC,
[PorConWmC]/1.73073 AS PorConBTUhrftF,
0.57109+0.0017625*[T]-0.0000067036*[T]^2 AS ConMoisture,
0.17881+0.0011958*[T]-0.0000027178*[T]*[T] AS ConProtein,
0.18071+0.00027604*[T]-0.00000017749*[T]*[T] AS ConFat,
0.20141+0.0013874*[T]-0.0000043312*[T]*[T] AS ConCarb,
0.18331+0.0012497*[T]-0.0000031683*[T]*[T] AS ConFiber,
0.32962+0.0014011*[T]-0.0000029069*[T]*[T] AS ConAsh,
997.18+0.0031439*[T]-0.0037574*[T]*[T] AS DenMoisture,
1329.9-0.5184*[T] AS DenProtein, 925.59-0.41757*[T] AS DenFat,
1599.1-0.31046*[T] AS DenCarb, 1311.5-0.36589*[T] AS DenFiber,
2423.8-0.28063*[T] AS DenAsh, 4.1762-0.000090864*[T]
+0.0000054731*[T]*[T] AS HtCapMoisture,
2.0082+0.0012089*[T]-0.00000113129*[T]*[T] AS HtCapProtein,
1.9842+0.0014733*[T]-0.0000048008*[T]*[T] AS HtCapFat,
1.5488+0.0019625*[T]-0.0000059399*[T]*[T] AS HtCapCarb,
1.8459+0.0018306*[T]-0.0000046509*[T]*[T] AS HtCapFiber,
1.0926+0.0018896*[T]-0.0000036817*[T]*[T] AS HtCapAsh, (Nz([Moisture],
[Moisturec])*[ConMoisture]+[Protein]*[ConProtein]+[Fat]*[ConFat]+
[Carbohydrates]*[ConCarb]+[Fiber]*[ConFiber]+[Ash]*[ConAsh])/100 AS
VConWms, [VConWms]/1.73073 AS VConBTUhrftF, 1/([MoisturecC]/
[DenMoisture]+[Protein]/[DenProtein]+[Fat]/[DenFat]+[Carbohydrates]/
[DenCarb]+[Fiber]/[DenFiber]+[Ash]/[DenAsh])/10 AS VDengmcc, [Vdengmcc]
+8.3454044518 AS VDenlbgalgmcc, [Vdengmcc]*62.427960576 AS VDenlbcuft,
[VDenlbcuft]*0.13368055555 AS VDenlbgalcuft, (Nz([Moisture],
[Moisturec])*[HtCapMoisture]+[Protein]*[HtCapProtein]+[Fat]*[HtCapFat]+
[Carbohydrates]*[HtCapCarb]+[Fiber]*[HtCapFiber]+[Ash]*[HtCapAsh])/100
AS VHtCapkJkgC, [VHtCapkJkgC]/4.1868 AS VHtCapBTUlbF,
1.73073*(0.014+(0.0183-0.014)/100*[T]) AS AirCon, IIf(Nz([AppDensity],
0)<>0,[VDengmcc]/[AppDensity]-1,Null) AS VolairVolmix,
tblMZFAINGPhysicalAttributes.Comments
FROM tblMZFAINGPhysicalAttributes
ORDER BY tblMZFAINGPhysicalAttributes.txtProfileID;
The value that I need to store in my table is calculated in the
VDenlbgalcuft field.

- Show quoted text -
 
J

jlute

Thanks, Dale. What do you mean by "function"?

You know,  another thing you might want to consider is creating a function
that computes the value that you want to store.  Then, you could pass the
function the appropriate parameters.  This way, you could use the function in
a query, or you could call it for only a single record in the AfterUpdateof
certain fields on a form.

I think this would be far more efficient than re-running the query, and far
easier to maintain, interpret, and understand.

--
HTH
Dale

Don''t forget to rate the post if it was helpful!

email address is invalid
Please reply to newsgroup only.









- Show quoted text -
 
D

Dale Fye

J,

First of all, I'm not sure how well your query will work as is, because in
your computation for CompTotalDiff, you are computing a numeric value against
a string in the expression:

IIF([CompTotal] = "0" or [CompTotal] = "100"

You also don't have the proper number of paramters in the nested IIF
function for the same value, the computation for MoistureC will end up as
NULL if either of the other values is Null. One of the real advantages of
writing this as a function is that it makes you think through your logic.

Back to topic. In Access you can create user defined functions that perform
calculations for you and return a value back to whatever event called them.
For example, I could create a function to convert degrees Farenheit to
degrees Celsius. To do this, I would select the Modules tab in the Access
database window (or nav pane) and would create a new module. Then I would
add some code to it that looks something like:

Public Function fnFarToCelsius(Degrees as double) as double

fnFarToCelsius = (Degrees - 32) * 5 / 9

End Function

I could then call this function from anywhere in my application, a form, a
query, or in the debug window. All I would have to do is pass it a degree
value and it would return the Celsius equivalent.

Likewise, you could create a function to perform your calculation for you.
It might start out something like:

Public Function fnVDenlbgalcuft(ServingWeight as Variant, SWUOM as Variant,
ProcessTemp as Variant, Moisture as Variant, Protein as Variant, Fat as
Variant, Carbs as Variant, Fiber as Variant, Ash as Variant) as single

Dim CompTotal as single
Dim CompTotalDiff as Variant
Dim MoistureC as Variant

CompTotal = NZ(Moisture, 0) + NZ(Protein, 0) + NZ(Fat, 0) _
+ NZ(Carbs, 0) + NZ(Fiber, 0) + NZ(Ash, 0)

'I'm not exactly sure what you are trying to do here.
'If CompTotal is 50, then CompTotalDiff = -50, is that what you want?
IF CompTotal = 0 OR CompTotal = 100 Then
CompTotalDiff = NULL
Elseif CompTotal <> 100 then
CompTotalDiff = CompTotal - 100
Else
CompTotalDiff = ????
Endif

'I've added the NZ( ) wrapper around these. Otherwise, if
'either value was NULL, MoistureC would be NULL
MoistureC = NZ(Moisture, 0) - NZ(CompTotalDiff, 0)

'This next part is even screwier
'in your query, you are missing a parameter in the IIF clause
'You are also making a boolean comparison, with numeric values
IF MoistureC Then
MoistureCC = MoistureC
Else
MoistureCC = MoistureC
Endif

'This is all the further I'm going to go

fnVDenlbgalcuft = ????

End Function


You can see that as I went through your query and tried to define the
variables that you created on the fly, I found some problems. I would
recommend you continue to pursue this, as this code will be much easier to
read and to modify.
--
HTH
Dale

Don''t forget to rate the post if it was helpful!

email address is invalid
Please reply to newsgroup only.
 
J

jlute

J,

First of all, I'm not sure how well your query will work as is, because in
your computation for CompTotalDiff, you are computing a numeric value against
a string in the expression:

IIF([CompTotal] = "0" or [CompTotal] = "100"

I've been running it for a few days and with many scenarios and it's
behaving as expected. There's good reason for all of the
"peculiarities" and perhaps I haven't constructed things as well as
they could/should be but it works.

CompTotalDiff is computed in this way so that Moisture can be
automatically adjusted to a "corrected" CompTotalc of 100. In other
You also don't have the proper number of paramters in the nested IIF
function for the same value, the computation for MoistureC will end up as
NULL if either of the other values is Null.

That's the desire :)
 One of the real advantages of
writing this as a function is that it makes you think through your logic.

You think on a much higher level! My "function" is a pencil and
paper!
Back to topic.  In Access you can create user defined functions that perform
calculations for you and return a value back to whatever event called them.  
For example, I could create a function to convert degrees Farenheit to
degrees Celsius.  To do this, I would select the Modules tab in the Access
database window (or nav pane) and would create a new module.  Then I would
add some code to it that looks something like:

Public Function fnFarToCelsius(Degrees as double) as double

    fnFarToCelsius = (Degrees - 32) * 5 / 9

End Function

I could then call this function from anywhere in my application, a form, a
query, or in the debug window.  All I would have to do is pass it a degree
value and it would return the Celsius equivalent.

Gotcha. That's slick and now that I understand your explanation it
seems to me that I've seen where people design these for command
buttons, etc. I'm just not to this level of design yet (and may never
be!).
Likewise, you could create a function to perform your calculation for you..  
It might start out something like:

Here's where I finally understand but not well enough to put the idea
to use. This is all well over my head!
Public Function fnVDenlbgalcuft(ServingWeight as Variant, SWUOM as Variant,
ProcessTemp as Variant, Moisture as Variant, Protein as Variant, Fat as
Variant, Carbs as Variant, Fiber as Variant, Ash as Variant) as single

    Dim CompTotal as single
    Dim CompTotalDiff as Variant
    Dim MoistureC as Variant

    CompTotal = NZ(Moisture, 0) + NZ(Protein, 0) + NZ(Fat, 0) _
                    + NZ(Carbs, 0) + NZ(Fiber, 0) + NZ(Ash, 0)

    'I'm not exactly sure what you are trying to do here.
    'If CompTotal is 50, then CompTotalDiff = -50, is that what youwant?

The query is the record source for a form and I wanted CompTotal to
"add up" visually for a user. Writing it with Nz allows this to
happen. Maybe not the "right" way but it works and I'm all about
getting things to work one way or another. The idea here is to simply
arrive at a total which is then adjusted per the above.
    IF CompTotal = 0 OR CompTotal = 100 Then
        CompTotalDiff = NULL
    Elseif CompTotal <> 100 then
        CompTotalDiff = CompTotal - 100
    Else
        CompTotalDiff = ????
    Endif

    'I've added the NZ( ) wrapper around these.  Otherwise, if
    'either value was NULL, MoistureC would be NULL
    MoistureC = NZ(Moisture, 0) - NZ(CompTotalDiff, 0)

CompTotalDiff: IIf([CompTotal]="0" Or
[CompTotal]="100",Null,IIf([CompTotal]<>100,([CompTotal]-100)))

This works as desired. If CompTotal is "0" or "100" then display Null
because neither value should be argued against 100. Iff CompTotal is
    'This next part is even screwier
    'in your query, you are missing a parameter in the IIF clause
    'You are also making a boolean comparison, with numeric values
    IF MoistureC Then
        MoistureCC = MoistureC
    Else
        MoistureCC = MoistureC
    Endif

Part of the need to adjust Moisture to correct the total. Goofy I
know.
    'This is all the further I'm going to go

I don't blame you!
You can see that as I went through your query and tried to define the
variables that you created on the fly, I found some problems.  I would
recommend you continue to pursue this, as this code will be much easier to
read and to modify.

I'm afraid at the moment that this is well beyond me and I'm going to
have to clunk along with what I've got until I get smarter!

Thanks for the ideas and knowledge!
 
J

jlute

BTW Dale - for any curiosity you might have here's the SQL for the
other query that I needed to join to the query in question. It's bound
to be screwy, too but it works! Its underlying queries do some equally
screwy things, too. I guess this is the result akin to asking a boy to
do a man's job!

As I noted I couldn't join the queries because it resulted in the "too
complex" error. The solution here to "push" the calcuated value to a
table works and I'll look to improve things in the near future.

SELECT tblFGPhysicalAttributes.txtProfileID, tblProfiles.Version,
tblProfiles.Description, tblProfiles.Status,
qryProfilesGroupsFG.GroupDesc,
tblFGPhysicalAttributes.UnitDescription,
tblFGPhysicalAttributes.ShippedIn, tblFGPhysicalAttributes.UnitCount,
tblFGPhysicalAttributes.SubUnitCount,
tblFGPhysicalAttributes.UnitSize, tblFGPhysicalAttributes.UnitUOM,
IIf([UnitUOM]="Ct.",+Nz([UnitCount],1)*Nz([SubUnitCount],
1)*[UnitSize],Null) AS UnitSizeCt, IIf([UnitUOM]="Ct.",Null,
+IIf([SubUnitCount],[SubUnitCount]*[UnitSize],[UnitSize])) AS
UnitSizeCtc, Nz([UnitSizeCt],[UnitSizeCtc]) AS UnitSizec,
IIf([UnitUOM]="Ct.",[UnitSizec],[UnitCount]) AS UnitCountc,
qryFGsINGsDensAllergens.Densitylbgal,
qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfSUBUNPRODWtlb AS
SUBUNPRODWt,
qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfSUBUNPRODWtlbTotal AS
SUBUNPRODWtTotal,
qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfUNPRODWtlb AS PRODWt,
qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfUNPPRODWtlbTotal AS
PRODWtTotal,
qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfSUBUNPKWtlbTotal AS
SUBUNPKWtTotal, qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfUNPKWtlb
AS UNPKWt, qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfUNPKWtlbTotal
AS UNPKWtTotal, Round([UnitSizec]*[lbConvFactor],6) AS UNNtWtConvlb,
Round([UnitSizec]*[galConvFactor],6) AS UNNtWtConvgal,
IIf(IsNull([SubUnitCount]),[UnitCount]*[PRODWt],
[UnitCount]*[SUBUNPRODWtTotal]) AS UNPRODNtWt, Nz([UNNtWtConvlb],
[UNNtWtConvgal]*[Densitylbgal]) AS UNNtWtNz, Nz([UNPRODNtWt],
[UNNtWtNz]) AS UNNtWtNzc, Round([UNNtWtNzc],6) AS UNNtWt,
Round([UNNtWt]*0.1+[UNNtWt],6) AS UNEstNtWt, IIf(Nz([SUBUNPKWtTotal],
0)<>0,Round([SUBUNPKWtTotal]+[UNEstNtWt],6),Round([SumOfSumOfUNPKWtlb]+
[UNEstNtWt],6)) AS UNEstGrWt, [UNEstGrWt]-[UNEstNtWt] AS UNPKNtWt,
[UNPKNtWt]/[UNEstGrWt] AS UNPKpercent,
qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfCSPKWtlb AS CSPKWt,
qryPKProfilesAssociationsPKWTsFGs.SumOfSumOfCSPKWtlbTotal AS
CSPKWtTotal, Nz([PRODWtTotal],([UnitCount]*[UNNtWt])) AS CSNtWtNz,
Round([CSNtWtNz],6) AS CSNtWt, Round([UnitCount]*[UNEstNtWt],6) AS
CSEstNtWt, Round([UNEstGrWt]*[UnitCount]+[CSPKWtTotal],6) AS
CSEstGrWt, [CSEstGrWt]-[CSEstNtWt] AS CSPKNtWt, [CSPKNtWt]/[CSEstGrWt]
AS CSPKpercent, tblFGPhysicalAttributes.UnitLoadStack,
IIf([UnitLoadStack]="Single","1",IIf([UnitLoadStack]="Double","2",IIf([UnitLoadStack]="Triple","3")))
AS ULStackFactor, tblFGPhysicalAttributes.Ti,
tblFGPhysicalAttributes.Hi, tblFGPhysicalAttributes.AdditionalUnits,
[Ti]*[Hi]+[AdditionalUnits] AS ULTotal,
[UnitCountc]*[ULTotal]*[ULStackFactor] AS ULSUV, Round([ULL],4) AS
ULLr, Round([ULW],4) AS ULWr, Round([ULHinConv],4) AS ULHinConvr,
qryPKProfilesAssociationsPKWTsFGsULDims.ULcuin,
qryPKProfilesAssociationsPKWTsFGsULDims.ULcuft,
[SumOfSumOfPTPKWtlb]*[ULStackFactor] AS PTPKWt,
[SumOfSumOfPTPKWtlbTotal]*[ULStackFactor] AS PTPKWtTotal,
IIf([UnitUOM]="Ct.",Round([PRODWt]*[ULSUV],
6),IIf(IsNull([CSNtWt]),Round([UNNtWt]*[ULTotal],
6),Round([UNNtWt]*[ULSUV],6))) AS ULNtWt,
IIf([UnitUOM]="Ct.",Round([ULNtWt]*0.1+[ULNtWt],
6),IIf(IsNull([CSNtWt]),Round([UNEstNtWt]*[ULTotal],
6),Round([UNEstNtWt]*[ULSUV],6))) AS ULEstNtWt,
IIf([CSEstGrWt],Round([CSEstGrWt]*[ULTotal]*[ULStackFactor]+
[PTPKWtTotal],6),Round([UNEstGrWt]*[ULTotal]*[ULStackFactor]+
[PTPKWtTotal],6)) AS ULEstGrWt, [ULEstGrWt]-[ULEstNtWt] AS ULPKNtWt,
[ULPKNtWt]/[ULEstGrWt] AS ULPKpercent,
tblProfilesStorage.StorageCondition, Round([UNL],4) AS UNLr,
Round([UNW],4) AS UNWr, Round([UNH],4) AS UNHr,
qryPKWTCalcsUNCSDims.UNcuin, qryPKWTCalcsUNCSDims.UNcuft, Round([CSL],
4) AS CSLr, Round([CSW],4) AS CSWr, Round([CSHc],4) AS CSHcr,
qryPKWTCalcsUNCSDims.CScuinc, qryPKWTCalcsUNCSDims.CScuftc,
qryFGsINGsDensAllergens.ProfilesAssociations AS FAING,
qryFGsINGsDensAllergens.Allergens, qryFGProcessingDrumNumbers.Drums
FROM ((((((((tblFGPhysicalAttributes LEFT JOIN tblUOMVolumeLiquidMass
ON tblFGPhysicalAttributes.UnitUOM =
tblUOMVolumeLiquidMass.txtUOMVolumeLiquid) LEFT JOIN
tblProfilesStorage ON tblFGPhysicalAttributes.txtProfileID =
tblProfilesStorage.txtProfileID) LEFT JOIN
qryPKProfilesAssociationsPKWTsFGs ON
tblFGPhysicalAttributes.txtProfileID =
qryPKProfilesAssociationsPKWTsFGs.txtProfileID) LEFT JOIN
qryPKProfilesAssociationsPKWTsFGsULDims ON
tblFGPhysicalAttributes.txtProfileID =
qryPKProfilesAssociationsPKWTsFGsULDims.txtProfileID) INNER JOIN
qryPKWTCalcsUNCSDims ON tblFGPhysicalAttributes.txtProfileID =
qryPKWTCalcsUNCSDims.txtProfileID) LEFT JOIN
qryFGProcessingDrumNumbers ON tblFGPhysicalAttributes.txtProfileID =
qryFGProcessingDrumNumbers.txtProfileID) LEFT JOIN qryProfilesGroupsFG
ON tblFGPhysicalAttributes.txtProfileID =
qryProfilesGroupsFG.txtProfileID) LEFT JOIN qryFGsINGsDensAllergens ON
tblFGPhysicalAttributes.txtProfileID =
qryFGsINGsDensAllergens.txtProfileID) INNER JOIN tblProfiles ON
tblFGPhysicalAttributes.txtProfileID = tblProfiles.txtProfileID;

J,

First of all, I'm not sure how well your query will work as is, because in
your computation for CompTotalDiff, you are computing a numeric value against
a string in the expression:

IIF([CompTotal] = "0" or [CompTotal] = "100"

You also don't have the proper number of paramters in the nested IIF
function for the same value, the computation for MoistureC will end up as
NULL if either of the other values is Null.  One of the real advantagesof
writing this as a function is that it makes you think through your logic.

Back to topic.  In Access you can create user defined functions that perform
calculations for you and return a value back to whatever event called them.  
For example, I could create a function to convert degrees Farenheit to
degrees Celsius.  To do this, I would select the Modules tab in the Access
database window (or nav pane) and would create a new module.  Then I would
add some code to it that looks something like:

Public Function fnFarToCelsius(Degrees as double) as double

    fnFarToCelsius = (Degrees - 32) * 5 / 9

End Function

I could then call this function from anywhere in my application, a form, a
query, or in the debug window.  All I would have to do is pass it a degree
value and it would return the Celsius equivalent.

Likewise, you could create a function to perform your calculation for you..  
It might start out something like:

Public Function fnVDenlbgalcuft(ServingWeight as Variant, SWUOM as Variant,
ProcessTemp as Variant, Moisture as Variant, Protein as Variant, Fat as
Variant, Carbs as Variant, Fiber as Variant, Ash as Variant) as single

    Dim CompTotal as single
    Dim CompTotalDiff as Variant
    Dim MoistureC as Variant

    CompTotal = NZ(Moisture, 0) + NZ(Protein, 0) + NZ(Fat, 0) _
                    + NZ(Carbs, 0) + NZ(Fiber, 0) + NZ(Ash, 0)

    'I'm not exactly sure what you are trying to do here.
    'If CompTotal is 50, then CompTotalDiff = -50, is that what youwant?
    IF CompTotal = 0 OR CompTotal = 100 Then
        CompTotalDiff = NULL
    Elseif CompTotal <> 100 then
        CompTotalDiff = CompTotal - 100
    Else
        CompTotalDiff = ????
    Endif

    'I've added the NZ( ) wrapper around these.  Otherwise, if
    'either value was NULL, MoistureC would be NULL
    MoistureC = NZ(Moisture, 0) - NZ(CompTotalDiff, 0)

    'This next part is even screwier
    'in your query, you are missing a parameter in the IIF clause
    'You are also making a boolean comparison, with numeric values
    IF MoistureC Then
        MoistureCC = MoistureC
    Else
        MoistureCC = MoistureC
    Endif

    'This is all the further I'm going to go

   fnVDenlbgalcuft = ????

End Function

You can see that as I went through your query and tried to define the
variables that you created on the fly, I found some problems.  I would
recommend you continue to pursue this, as this code will be much easier to
read and to modify.
--
HTH
Dale

Don''t forget to rate the post if it was helpful!

email address is invalid
Please reply to newsgroup only.



Thanks, Dale. What do you mean by "function"?

- Show quoted text -
 

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