功能MOD上的Excel错误

时间:2016-06-22 11:13:32

标签: excel vba excel-vba

我想在excel文件中输入此公式(最好是VBA)。但是由于某种原因,当我把这个函数放在我的公式栏中时出现错误:

Declare @StartTime DateTime2 = getDate()

your query...

Select datediff(ms, @StartTime, getdate())

我的功能是:

#NUM! - Number Error

但是当我只输入10位数字时,它就可以了。我需要使用16位数。 我基本上尝试根据ISO 7064 Mod 97,10公式验证号码 提前谢谢。

感谢人们,为了你的努力,但是我已经尝试了@Robyn编写的代码,并且我得到了溢出错误。这是我的代码(我将只写函数部分): '注意:输入参数为:3259300700853850和97

=98-mod(2000000000123456*100;97))

4 个答案:

答案 0 :(得分:4)

如前所述,Excel具有15位精度的限制。因此,当您输入上面的公式时,您的16位数字将被更改:

2000000000123456变为2000000000123460

解决此限制的一种方法是使用VBA并更改公式。

不是编写16 digit number * 100,而是将整个值输入为字符串:

" 200000000012345600"

例如:

=98-xMOD("200000000012345600";97)

然后使用此UDF,它利用VBA的Decimal数据类型提供的更高精度:

Option Explicit
Function xMOD(Num As Variant, Div As Long)
    Dim x As Variant, y As Variant

x = CDec(Num)
y = CDec(Div)

xMOD = x - Int(x / y) * y

End Function

如果您要在某个单元格中输入16位数字(作为字符串),并且始终乘以100,则可以使用以下公式:

=98-xMOD(C1&"00";97)

或者,您只需在某个单元格中输入18位数字作为字符串,并在公式中引用它,省略&"00"部分。

另一个选项,如果你能找到它,将是一个名为xNumbers的不受支持的免费加载项。最新版本6.0仍适用于Excel 2016,但与功能区的集成不存在,因此无法使用某些配置选项。

编辑由于你写道你无法让这个UDF在你的系统中工作,我会发布一个屏幕截图,显示它在我的网站上工作,并且它同意结果你已经在你的赏金描述中发布了。 (来自xNumbers的xIntMod也返回相同的结果)

enter image description here

答案 1 :(得分:0)

对于abs()小于或等于2,147,483,647的数字

根据Microsoft支持文章XL: MOD() Function Returns #NUM! Error Value,这是一个已知问题。

请注意,这篇文章过时了 - 所以这可能不是您实例中的真正根本原因。

本文建议以下作为解决方法:

  

不使用此公式=MOD(J13,K13),而是使用以下公式:=J13-(INT(J13/K13)*K13)

或者,this article表示VBA等价物:

Function DblMod(Dividend, Divisor)
    ' Declare two double precision variables
    Dim D1 As Double
    Dim D2 As Double

    ' Copy function arguments to local variables
    D1 = Dividend
    D2 = Divisor

    DblMod = D1 Mod D2
End Function

对于abs()大于2,147,483,647

的数字

在这种情况下,VBA MOD函数溢出Run Time Error '6': Overflow。 Microsoft支持文章PRB: "Overflow" with Integer Division and MOD Operator中对此进行了解决。文章在VBA中提出了以下解决方案,我已经测试了OP的给定数字:

Sub Main()
    Call DblMod2(3259300700853850, 97) 
    ' returns 46, which matches the Big Integer Calculator at http://www.javascripter.net/math/calculators/100digitbigintcalculator.htm suggested by Ron
End Sub

Function DblMod2(Dividend, Divisor)

    Dim dblX As Double
    Dim dblY As Double
    dblX = Dividend               ' numerator
    dblY = Divisor                ' denominator

    ' round off the numerator and denominator (ensure number is .0)
    dblX = Int(dblX + 0.5)
    dblY = Int(dblY + 0.5)

    ' Emulate integer division with: Fix(dblX / dblY)
    ' Emulate modulo arithmetic with: dblX - (dblY * Fix(dblX / dblY))
    DblMod2 = dblX - (dblY * Fix(dblX / dblY))
    Debug.Print DblMod2
End Function

答案 2 :(得分:0)

MOD函数here

有一个替代
Function DblMod(Dividend, Divisor)
    ' Declare two double precision variables
    Dim D1 As Double
    Dim D2 As Double
    Dim D3 As Double
    Dim str1
    Dim Str2
    ' Copy function arguments to local variables
    D1 = CDbl(Dividend)
    D2 = Divisor
    DblMod = CDec(D1) - (Round(CDec(D1) / D2) * D2)
End Function

编辑1

尝试使用以下内容,它将返回46

Sub test()
    test = DblMod("3259300700853850", 97)
End Sub
<script>
    players = new Array();
    alert($("iframe.yt_players"));
    function onYouTubeIframeAPIReady() {
        var temp = $("iframe.yt_players");    
        for (var i = 0; i < temp.length; i++) {
            var t = new YT.Player($(temp[i]).attr('id'), {
            events: {
                'onStateChange': onPlayerStateChange
            }
        });
            players.push(t);
        }
    }

    function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING) {
            var temp = event.target.a.src;
            var tempPlayers = $("iframe.yt_players");
            for (var i = 0; i < players.length; i++) {
                if (players[i].a.src != temp) players[i].stopVideo();

            }
        }
    }

    window.onload = onYouTubeIframeAPIReady;
    </script>

答案 3 :(得分:0)

不要处理非常大的数字,而是将它们分开:

Public Function ExtMod(Dividend As String, Divisor As Long) As Double
  Dim i As Long, j As Double
  For i = 1 To Len(Dividend)
    If Not IsNumeric(Mid(Dividend, i, 1)) Then
      j = j & Mid(Dividend, i)
      Exit For
    End If
    j = j * 10 + Mid(Dividend, i, 1)
    While j >= Divisor
      j = j - Divisor
    Wend
  Next
  ExtMod = j
End Function

也适用于小数和区域设置应该无关紧要。唯一的限制是你可能永远不会达到的字符串的最大长度。

用&#34; 123456789012345678901234567890.3241543&#34;进行测试和643这是435.3241543。

如果您有任何疑问,请询问;)