Excel自定义函数不在多个工作表中重新计算

时间:2017-01-25 00:47:37

标签: excel vba excel-vba

如果这个问题格式不正确,我现在就要道歉,因为我是这个网站的新手。

一位同事编写了所有代码并启动了我完成的数组(数组)以创建下面的UDF以减少我之前使用的公式数量,以找到不同金属的材料密度并将公式修改为需要根据零件的形状来计算重量。

我遇到的问题是这个UDF用在一个工作簿中的多个工作表(45张)中,所有工作表总计到摘要选项卡。为了使所有工作表公式正确计算,我要么必须双击每个单独的单元格以强制它重新计算,要么我突出显示所有单元格并转到数据>文本到列>然后单击“完成”以强制重新计算所有突出显示的单元格。

我尝试使用快捷方式(即 Ctrl + ALT + Shift + F9 强制使用UDF重新计算)以及代码开头的Application.Volatile,但它们只重新计算一个工作表而不是所有工作表。它没有重新计算的工作表在单元格中显示#value!

由于我不是唯一使用此文档的人,这给我自己带来了麻烦。

这是代码。写这篇文章的同事提供了一些文字,以帮助我将来对其进行故障排除。

' We want our function to do the following:
' 1)  Create new function called "MATWEIGHT" and the output I want is a Double (a decimal number)  
' 2)  The inputs I want to bring into the function are "size" and "matl" which are a double and a string respectively.

Public Function MatType(matl As String) As Double

    'Dim outputWeight As Double      'This is a variable declaration - it's good to assign our output to a temporary variable
    'outputWeight = size * 2         'Take the size and multiply by 2
    'MATWEIGHT = outputWeight & matl       'Set the function name to our output to give us our answer

    Dim MatType1(98, 1) As String
    Dim flag As Integer
    flag = 0
    Dim matlDes As String
    matlDes = ""

    MatType1(0, 0) = "304SS - ANGLE"
    MatType1(1, 0) = "304SS - CHANNEL"
    MatType1(2, 0) = "304SS - FLAT BAR"
    MatType1(3, 0) = "304SS - HSS"
    MatType1(4, 0) = "304SS - I-BEAM"
    MatType1(5, 0) = "304SS - PIPE"
    MatType1(6, 0) = "304SS - PLATE"
    MatType1(7, 0) = "304SS - ROUND BAR"
    MatType1(8, 0) = "304SS - SQUARE BAR"
    MatType1(9, 0) = "304SS - WF BEAM"
    MatType1(10, 0) = "410SS - FLAT BAR"
    MatType1(11, 0) = "410SS - PLATE"
    MatType1(12, 0) = "410SS - ROUND BAR"
    MatType1(13, 0) = "420SS - FLAT BAR"
    MatType1(14, 0) = "420SS - PLATE"
    MatType1(15, 0) = "420SS - ROUND BAR"
    MatType1(16, 0) = "44W - PLATE"
    MatType1(17, 0) = "44W CAT 1 - PLATE"
    MatType1(18, 0) = "50W - ANGLE"
    MatType1(19, 0) = "50W - BAR GRATING"
    MatType1(20, 0) = "50W - CHANNEL"
    MatType1(21, 0) = "50W - MC CHANNEL"
    MatType1(22, 0) = "50W - FLAT BAR"
    MatType1(23, 0) = "50W - HSS"
    MatType1(24, 0) = "50W - I-BEAM < 8in"
    MatType1(25, 0) = "50W - I-BEAM > 10in"
    MatType1(26, 0) = "50W - PIPE"
    MatType1(27, 0) = "50W - PLATE"
    MatType1(28, 0) = "50W - ROUND BAR"
    MatType1(29, 0) = "50W - SQUARE BAR"
    MatType1(30, 0) = "50W - WF BEAM"
    MatType1(31, 0) = "50W CAT 3 - PLATE"
    MatType1(32, 0) = "630SS - FLAT BAR"
    MatType1(33, 0) = "630SS - PLATE"
    MatType1(34, 0) = "630SS - ROUND BAR"
    MatType1(35, 0) = "700QT - PLATE"
    MatType1(36, 0) = "ALUMINUM - ANGLE"
    MatType1(37, 0) = "ALUMINUM - CHANNEL"
    MatType1(38, 0) = "ALUMINUM - FLAT BAR"
    MatType1(39, 0) = "ALUMINUM - HSS"
    MatType1(40, 0) = "ALUMINUM - I-BEAM"
    MatType1(41, 0) = "ALUMINUM - PIPE"
    MatType1(42, 0) = "ALUMINUM - PLATE"
    MatType1(43, 0) = "ALUMINUM - ROUND BAR"
    MatType1(44, 0) = "ALUMINUM - SQUARE BAR"
    MatType1(45, 0) = "ALUMINUM - WF BEAM"
    MatType1(46, 0) = "BRASS - PIPE"
    MatType1(47, 0) = "BRASS - PLATE"
    MatType1(48, 0) = "BRASS - ROUND BAR"
    MatType1(49, 0) = "BRONZE - PIPE"
    MatType1(50, 0) = "BRONZE - PLATE"
    MatType1(51, 0) = "BRONZE - ROUND BAR"
    MatType1(52, 0) = "NYLATRON - PLATE"
    MatType1(53, 0) = "NYLATRON - ROUND BAR"
    MatType1(54, 0) = "UHMW - PLATE"
    MatType1(55, 0) = "UHMW - ROUND BAR"
    MatType1(56, 0) = "ANCHORS"
    MatType1(57, 0) = "BUSHINGS"
    MatType1(58, 0) = "ROLLER - AXLE"
    MatType1(59, 0) = "ROLLER - BEARING"
    MatType1(60, 0) = "ROLLER - SEALS"
    MatType1(61, 0) = "ROLLER - WHEEL"
    MatType1(62, 0) = "ROLLER ASS'Y, 210 DIA."
    MatType1(63, 0) = "ROLLER ASS'Y, 270 DIA."
    MatType1(64, 0) = "ROLLER ASS'Y, 380 DIA."
    MatType1(65, 0) = "ROLLER ASS'Y, 440 DIA."
    MatType1(66, 0) = "ROLLER ASS'Y, 660 DIA."
    MatType1(67, 0) = "ROLLER ASS'Y, 228 DIA."
    MatType1(68, 0) = "ROLLER ASS'Y, 250 DIA."
    MatType1(69, 0) = "ROLLER ASS'Y, 381 DIA."
    MatType1(70, 0) = "ROLLER ASS'Y, 457 DIA."
    MatType1(71, 0) = "ROLLER ASS'Y, 530 DIA."
    MatType1(72, 0) = "GUIDE WHEEL ASSEMBLIES"
    MatType1(73, 0) = "GUIDE WHEEL ASSEMBLIES W/ SPRINGS"
    MatType1(74, 0) = "HARDWARE"
    MatType1(75, 0) = "HEATERS, GAIN"
    MatType1(76, 0) = "MACHINING INSERTS"
    MatType1(77, 0) = "MISC"
    MatType1(78, 0) = "NAME PLATES"
    MatType1(79, 0) = "PAINT - CHEAP"
    MatType1(80, 0) = "PAINT - MIDDLE"
    MatType1(81, 0) = "PAINT - EXPENSIVE"
    MatType1(82, 0) = "RIGGING, SHACKLES"
    MatType1(83, 0) = "RIGGING, WIRE ROPE SLINGS"
    MatType1(84, 0) = "RUBBER"
    MatType1(85, 0) = "SEALS - FRAME"
    MatType1(86, 0) = "SEALS - BULB"
    MatType1(87, 0) = "SEALS - BOTTOM"
    MatType1(88, 0) = "SEALS - WIND"
    MatType1(89, 0) = "SHEAVE BUSHING"
    MatType1(90, 0) = "SHEAVE PIN"
    MatType1(91, 0) = "SHEAVES"
    MatType1(92, 0) = "SPRINGS"
    MatType1(93, 0) = "STAIR TREADS"
    MatType1(94, 0) = "TBD"
    MatType1(95, 0) = "WELDING WIRE - MILD STEEL"
    MatType1(96, 0) = "WELDING WIRE - STAINLESS"
    MatType1(97, 0) = "WOOD"
    MatType1(98, 0) = "GUIDE ROLLER - WHEEL"
    MatType1(0, 1) = "Structural"
    MatType1(1, 1) = "Structural"
    MatType1(2, 1) = "Plate / Flat Bar"
    MatType1(3, 1) = "Structural"
    MatType1(4, 1) = "Structural"
    MatType1(5, 1) = "Structural"
    MatType1(6, 1) = "Plate / Flat Bar"
    MatType1(7, 1) = "Round Bar"
    MatType1(8, 1) = "Plate / Flat Bar"
    MatType1(9, 1) = "Structural"
    MatType1(10, 1) = "Plate / Flat Bar"
    MatType1(11, 1) = "Plate / Flat Bar"
    MatType1(12, 1) = "Round Bar"
    MatType1(13, 1) = "Plate / Flat Bar"
    MatType1(14, 1) = "Plate / Flat Bar"
    MatType1(15, 1) = "Round Bar"
    MatType1(16, 1) = "Plate / Flat Bar"
    MatType1(17, 1) = "Plate / Flat Bar"
    MatType1(18, 1) = "Structural"
    MatType1(19, 1) = "Bar Grating"
    MatType1(20, 1) = "Structural"
    MatType1(21, 1) = "Structural" = mat
    MatType1(22, 1) = "Plate / Flat Bar"
    MatType1(23, 1) = "Structural"
    MatType1(24, 1) = "Structural"
    MatType1(25, 1) = "Structural"
    MatType1(26, 1) = "Structural"
    MatType1(27, 1) = "Plate / Flat Bar"
    MatType1(28, 1) = "Round Bar"
    MatType1(29, 1) = "Plate / Flat Bar"
    MatType1(30, 1) = "Structural"
    MatType1(31, 1) = "Plate / Flat Bar"
    MatType1(32, 1) = "Plate / Flat Bar"
    MatType1(33, 1) = "Plate / Flat Bar"
    MatType1(34, 1) = "Round Bar"
    MatType1(35, 1) = "Plate / Flat Bar"
    MatType1(36, 1) = "Structural"
    MatType1(37, 1) = "Structural"
    MatType1(38, 1) = "Aluminum Plate / Flat Bar"
    MatType1(39, 1) = "Structural"
    MatType1(40, 1) = "Structural"
    MatType1(41, 1) = "Structural"
    MatType1(42, 1) = "Aluminum Plate / Flat Bar"
    MatType1(43, 1) = "Aluminum Round Bar"
    MatType1(44, 1) = "Aluminum Plate / Flat Bar"
    MatType1(45, 1) = "Structural"
    MatType1(46, 1) = "Brass Round Bar"
    MatType1(47, 1) = "Brass Plate / Flat Bar"
    MatType1(48, 1) = "Brass Round Bar"
    MatType1(49, 1) = "Brass Round Bar"
    MatType1(50, 1) = "Brass Plate / Flat Bar"
    MatType1(51, 1) = "Brass Round Bar"
    MatType1(52, 1) = "UHMW Plate / Flat Bar"
    MatType1(53, 1) = "UHMW Round Bar"
    MatType1(54, 1) = "UHMW Plate / Flat Bar"
    MatType1(55, 1) = "UHMW Round Bar"
    MatType1(56, 1) = "Everything Else"
    MatType1(57, 1) = "Everything Else"
    MatType1(58, 1) = "Round Bar"
    MatType1(59, 1) = "Everything Else"
    MatType1(60, 1) = "Everything Else"
    MatType1(61, 1) = "Everything Else"
    MatType1(62, 1) = "Everything Else"
    MatType1(63, 1) = "Everything Else"
    MatType1(64, 1) = "Everything Else"
    MatType1(65, 1) = "Everything Else"
    MatType1(66, 1) = "Everything Else"
    MatType1(67, 1) = "Everything Else"
    MatType1(68, 1) = "Everything Else"
    MatType1(69, 1) = "Everything Else"
    MatType1(70, 1) = "Everything Else"
    MatType1(71, 1) = "Everything Else"
    MatType1(72, 1) = "Everything Else"
    MatType1(73, 1) = "Everything Else"
    MatType1(74, 1) = "Everything Else"
    MatType1(75, 1) = "Everything Else"
    MatType1(76, 1) = "Everything Else"
    MatType1(77, 1) = "Everything Else"
    MatType1(78, 1) = "Everything Else"
    MatType1(79, 1) = "Everything Else"
    MatType1(80, 1) = "Everything Else"
    MatType1(81, 1) = "Everything Else"
    MatType1(82, 1) = "Everything Else"
    MatType1(83, 1) = "Everything Else"
    MatType1(84, 1) = "Everything Else"
    MatType1(85, 1) = "Everything Else"
    MatType1(86, 1) = "Seals"
    MatType1(87, 1) = "Seals"
    MatType1(88, 1) = "Seals"
    MatType1(89, 1) = "Everything Else"
    MatType1(90, 1) = "Round Bar"
    MatType1(91, 1) = "Everything Else"
    MatType1(92, 1) = "Everything Else"
    MatType1(93, 1) = "Everything Else"
    MatType1(94, 1) = "Everything Else"
    MatType1(95, 1) = "Everything Else"
    MatType1(96, 1) = "Everything Else"
    MatType1(97, 1) = "Everything Else"
    MatType1(98, 1) = "Everything Else"

    ' Find the address of the caller (the cell where the address is)
    Dim clr As Range
    Set clr = Application.Caller

    ' Find the row only of the caller
    Dim FRow As String
    FRow = clr.Row

    ' Search the range A1 to Z1 for vA, vC, vD, and vE
    Dim rng As Range
      Set rng = Range("A1:Z1")

      Dim vA As String
      Dim vC As String
      Dim vD As String
      Dim vE As String
      Dim lA As String
      Dim lC As String
      Dim lD As String
      Dim lE As String

      vA = "Quantity"
      vC = "Thick. / Dia."
      vD = "Width / #-ft"
      vE = "Length"

      For Each c In Range("A1:Z1").Cells
            If c.Value = vA Then
                lA = Left(Replace(c.Address, "$", ""), 1)
            End If

            If c.Value = vC Then
                lC = Left(Replace(c.Address, "$", ""), 1)
            End If

            If c.Value = vD Then
                lD = Left(Replace(c.Address, "$", ""), 1)
            End If

            If c.Value = vE Then
                lE = Left(Replace(c.Address, "$", ""), 1)
            End If
      Next c

    ' Setting the values from the corresponding ranges to the following variables
    Dim qty As String
    Dim thk As String
    Dim width As String
    Dim length As String

    qty = Range(lA & FRow).Value
    thk = Range(lC & FRow).Value
    width = Range(lD & FRow).Value
    length = Range(lE & FRow).Value

    For i = 0 To UBound(MatType1, 1)
        If matl = MatType1(i, 0) Then
            flag = 1
            matl = MatType1(i, 0)
            matlDes = CStr(MatType1(i, 1))
        End If
    Next i

    If flag = 1 Then
        If matlDes = "Plate / Flat Bar" Then
            MatType = Round(thk * width * length * 0.0000174 * qty, 2)
        End If


        If matlDes = "Structural" Then
            MatType = Round((length / 304.8) * width * qty, 2)
        End If

        If matlDes = "Round Bar" Then
            MatType = Round(((3.14 * (length * (thk / 2) * (thk / 2))) * 0.0000174) * qty, 2)
        End If

        If matlDes = "Aluminum Plate / Flat Bar" Then
            MatType = Round(((thk * width * length) * 0.00000595) * qty, 2)
        End If

        If matlDes = "Aluminum Round Bar" Then
            MatType = Round(((3.14 * (length * (thk / 2) * (thk / 2))) * 0.00000595) * qty, 2)
        End If

        If matlDes = "Brass Round Bar" Then
            MatType = Round(((3.14 * (length * (thk / 2) * (thk / 2))) * 0.00001851883) * qty, 2)
        End If

         If matlDes = "Brass Plate / Flat Bar" Then
            MatType = Round(((thk * width * length) * 0.00001851883) * qty, 2)
        End If

         If matlDes = "UHMW Plate / Flat Bar" Then
            MatType = Round(thk * width * length * 0.03 * qty, 2)
        End If

         If matlDes = "UHMW Round Bar" Then
            MatType = Round((3.14 * (length / 25.4) * (((thk / 2) / 25.4) * ((thk / 2) / 25.4)) * qty) * 0.03, 2)
        End If

         If matlDes = "Seals" Then
            MatType = Round((length / 304.8) * qty, 2)
        End If

         If matlDes = "Bar Grating" Then
            MatType = Round((thk * (width / 304.8) * (length / 304.8)) * qty, 2)
        End If

         If matlDes = "Everything Else" Then
            MatType = Round(qty)
        End If


    End If



End Function

任何有关在单元格值更改和/或打开工作簿时重新计算所有选项卡的帮助都将非常感激。

提前致谢。

3 个答案:

答案 0 :(得分:1)

您没有将代码链接到调用工作表 - 您的无条件调用

Set rng = Range("A1:Z1") 

将始终引用任何活动的工作表,而不是具有公式的工作表(除非那是活动工作表...)

你需要在你的函数顶部做这样的事情:

Dim sht As WorkSheet
Set sht = Application.Caller.Worksheet

然后使用sht限定UDF中每个单一范围/单元格调用

请参阅What is the default scope of worksheets and cells and range?了解默认&#34;范围&#34;用于拨打Range / Cells

答案 1 :(得分:0)

在代码顶部使用:Application.volatile,这会导致您的功能在您更新/刷新工作簿时重新计算

答案 2 :(得分:0)

UDF(或任何Excel函数)在其一个或多个参数的值发生更改时重新计算。您应该将范围作为参数传递给UDF,而不是将这些范围硬编码到代码中。

作为模板,请考虑更改为

Public Function MatType(matl As String, qty As Range, thk As Range, width As Range, length As Range) As Double

您可以使用Application.Volitile强制它在每次重新计算时重新计算,但在这种情况下,这是低效且不必要的。如果您这样,您需要按照Tim的建议修复工作表范围 功能