简体   繁体   中英

Excel VBA Function Fails but Formula works in sheet

Weird Math Error in VBA for Excel

Hi all, would love feedback on unsusual error I'm getting.

Very strange. I have a simple formula that works great if I only use it in a normal sheet cell and copy it down by columns, but if I try to do a simple iteration in vba code to perform the same function I get the wrong values.

Description : A number is squared, then divided by another value between 0.99 to 1.99, next the modulus is taken and then the number is squared again and the whole formula repeated.
If I copy the formula statement down column wise it calcs fine, including reasonable decimal accuracy.

There are four inputs ; base value (inputx) decx = divisor mod value

The first formula placed at (E2) looks like ; =MOD(((B2^2)/$B$3),$B$4)

In (E3) this statement is placed ; =MOD(((E2^2)/$B$3),$B$4)

Then this exact same statement is copied down, columnwise to the next 98 cells.

All great, no problem. It seems accurate value wise, right to decimal precision, with values past the decimal point showing in all column cells.

Some sample input values for testing ;

INPUTX --> 231
DECX 1.010101
MOD 400
LOOPTIMES 100

But when I try to implement this is Excel VBA code (Excel 2007) I often get the wrong values and absolutely no values past the decimal point ever show.

Have tried using all kinds of different data types ; single, double, variant, etc... but all values returned by the VBA function I made always returns whole numbers, and is often wrong and certainly does not agree with the values returned by the simple column based statements.

Have tried to find ways around this or to fix this, came across "CDEC", tried this and nothing changed. Totally stumped and would love some insight into if this can be fixed so that the function loop returns the same values with same kind of decimal precision as the column based statements and would greatly appreciate feedback on how mthis can be done.

Am including my sample code below ;

Public Function SQRD(inputx As Variant, looptime As Variant, decx As Variant) As Variant

Application.Volatile

Dim Count As Integer

SQRD = CDec(inputx)

'Dim decx As variant

Count = 1

For Count = 1 To looptime
    SQRD = CDec(SQRD ^ 2)  '+ looptime
    SQRD = CDec(SQRD Mod 400 / decx)
Next Count

End Function

Lots amiss with your code. No need for looping as far as I can see, and you're dividing after the mod not before

This seems to do the trick

Public Function NuFunc(InputX As Variant, DecX As Variant) As Variant
  NuFunc = ((InputX ^ 2) / DecX) Mod 400
End Function

I will only address your use of the VBA Mod operator. It is NOT equivalent to the Excel MOD function. In particular, the VBA Mod operator will round floating point numbers to integers before performing the operation.

To use a VBA function that mimics the Excel MOD function, use something like:

Function xlMOD(a As Double, b As Double) As Double
    xlMOD = a - (b * (a \ b))
End Function

EDIT There seems to be a bug in VBA (or a documentation error). In the formula above, the \\ operator is supposed to be the integer division operator. It does return an integer result. However, it does not truncate, rather it rounds. Actually, what it may be doing, is performing VBA type rounding on the number and divisor, before returning the result.

Therefore, a proper vba function to mimic the Excel MOD function would be:

Function xlMOD(a As Double, b As Double) As Double   
    xlMOD = a - Int(a / b) * b
End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM