【问题标题】:Cell referencing not working in excel vba单元格引用在excel vba中不起作用
【发布时间】:2014-12-18 08:53:28
【问题描述】:

我编写了一个函数,它从工作表中获取输入,执行计算,然后在同一个工作表上输入结果。我这样做是为了测试代码的功能。

现在我需要让代码具有相同的功能,但要从 2 个不同的工作表中获取输入,然后写入其中一个。

让我们将工作表称为“数据”和“接口”

我最初使用Range 对象编写代码来引用单元格和范围,没有前体。我目前正在尝试将代码编写为分配给其中一张纸上的按钮的macro

我尝试过的事情:

激活适当的工作表并正常使用范围,例如

Worksheets("Data").Activate
pressure = Range("S2").Value

这会导致奇怪的错误,例如:

无法获取工作表函数类的匹配属性

完全限定所有 Range 对象,例如

ThisWorkbook.Sheets("Data").Range("A1")

与上述相同的错误。

使用命名范围引用某些单元格:

pressure = Range("Pressure").Value

根据我的阅读,这应该有效。我不知道为什么没有。

有没有好的或首选的方法来做到这一点?

完整代码(2 个函数,1 个子函数):

Function InterpolateAll(methane As Double, pressure As Double, temp As Double, column As Integer, m_range As Range, p_range As Range, t_range As Range, m1 As Double, m2 As Double, t1 As Double, t2 As Double, t3 As Double, t4 As Double, p1 As Double, p_1_index As Integer, p2 As Double, p_2_index As Integer, p3 As Double, p_3_index As Integer, p4 As Double, p_4_index As Integer, p5 As Double, p_5_index As Integer, p6 As Double, p_6_index As Integer, p7 As Double, p_7_index As Integer, p8 As Double, p_8_index As Integer) As Double

Worksheets("Data").Activate

Dim v1 As Double
Dim v2 As Double
Dim v3 As Double
Dim v4 As Double
Dim v5 As Double
Dim v6 As Double
Dim v7 As Double
Dim v8 As Double
Dim vr1 As Double
Dim vr2 As Double
Dim vr3 As Double
Dim vr4 As Double
Dim vrr1 As Double
Dim vrr2 As Double

v1 = cells(p_1_index, column)
v2 = cells(p_2_index, column)
v3 = cells(p_3_index, column)
v4 = cells(p_4_index, column)
v5 = cells(p_5_index, column)
v6 = cells(p_6_index, column)
v7 = cells(p_7_index, column)
v8 = cells(p_8_index, column)
vr1 = Interpolate(pressure, p1, p2, v1, v2)
vr2 = Interpolate(pressure, p3, p4, v3, v4)
vr3 = Interpolate(pressure, p5, p6, v5, v6)
vr4 = Interpolate(pressure, p7, p8, v7, v8)
vrr1 = Interpolate(temp, t1, t2, vr1, vr2)
vrr2 = Interpolate(temp, t3, t4, vr3, vr4)
vrrr = Interpolate(methane, m1, m2, vrr1, vrr2)

InterpolateAll = vrrr

End Function

Function Interpolate(a_desired As Double, a1 As Double, a2 As Double, p1 As Double, p2 As Double)

Interpolate = (a_desired - a1) / (a2 - a1) * (p2 - p1) + p1

End Function





Private Sub CommandButton3_Click()

Dim m1 As Double
Dim m2 As Double
Dim t1 As Double
Dim t2 As Double
Dim t3 As Double
Dim t4 As Double
Dim p1 As Double
Dim p2 As Double
Dim p3 As Double
Dim p4 As Double
Dim p5 As Double
Dim p6 As Double
Dim p7 As Double
Dim p8 As Double

Worksheets("Data").Activate

pressure = Range("S2").Value
temp = Range("R2").Value
percent_methane = Range("Q2").Value

start_range = Range("A1")


Dim m_range As Range
Dim p_range As Range
Dim t_range As Range
Dim m_start As Range
Dim p_start As Range
Dim t_start As Range


Set m_range = Range("A:A")
Set t_range = Range("B:B")
Set p_range = Range("C:C")
Set m_start = Range("A1")
Set t_start = Range("B1")
Set p_start = Range("C1")

m1 = m_range.Item(WorksheetFunction.Match(percent_methane, m_range))
m_range_1_top = WorksheetFunction.Match(percent_methane, m_range)
m_range_1_bottom = WorksheetFunction.Match(m1, m_range, 0)


m2 = m_range.Item(m_range_1_top + 1)
m_range_2_bottom = m_range_1_top + 1
m_range_2_top = WorksheetFunction.Match(m2, m_range)



t1 = t_range.Item(WorksheetFunction.Match(temp, Range(cells(m_range_1_bottom, 2), cells(m_range_1_top, 2))) + m_range_1_bottom - 1)

t_range_1_top = WorksheetFunction.Match(temp, Range(cells(m_range_1_bottom, 2), cells(m_range_1_top, 2))) + m_range_1_bottom - 1
t_range_1_bottom = WorksheetFunction.Match(t_range.Item(t_range_1_top), Range(cells(m_range_1_bottom, 2), cells(m_range_1_top, 2)), 0) + m_range_1_bottom - 1

t2 = t_range.Item(t_range_1_top + 1)

t_range_2_bottom = t_range_1_top + 1
t_range_2_top = WorksheetFunction.Match(t2, Range(cells(m_range_1_bottom, 2), cells(m_range_1_top, 2))) + m_range_1_bottom - 1

t_range_3_top = WorksheetFunction.Match(temp, Range(cells(m_range_2_bottom, 2), cells(m_range_2_top, 2))) + m_range_2_bottom - 1
t_range_3_bottom = WorksheetFunction.Match(t_range.Item(t_range_3_top), Range(cells(m_range_2_bottom, 2), cells(m_range_2_top, 2)), 0) + m_range_2_bottom - 1
t3 = t_range.Item(t_range_3_bottom)

t4 = t_range.Item(t_range_3_top + 1)

t_range_4_bottom = t_range_3_top + 1
t_range_4_top = WorksheetFunction.Match(t4, Range(cells(m_range_2_bottom, 2), cells(m_range_2_top, 2))) + m_range_2_bottom - 1

p_1_index = WorksheetFunction.Match(pressure, Range(cells(t_range_1_bottom, 3), cells(t_range_1_top, 3))) + t_range_1_bottom - 1
p1 = p_range.Item(p_1_index)

p_2_index = p_1_index + 1
p2 = p_range.Item(p_2_index)

p_3_index = WorksheetFunction.Match(pressure, Range(cells(t_range_2_bottom, 3), cells(t_range_2_top, 3))) + t_range_2_bottom - 1
p3 = p_range.Item(p_3_index)

p_4_index = p_3_index + 1
p4 = p_range.Item(p_4_index)

p_5_index = WorksheetFunction.Match(pressure, Range(cells(t_range_3_bottom, 3), cells(t_range_3_top, 3))) + t_range_3_bottom - 1
p5 = p_range.Item(p_5_index)

p_6_index = p_5_index + 1
p6 = p_range.Item(p_6_index)

p_7_index = WorksheetFunction.Match(pressure, Range(cells(t_range_4_bottom, 3), cells(t_range_4_top, 3))) + t_range_4_bottom - 1
p7 = p_range.Item(p_7_index)

p_8_index = p_7_index + 1
p8 = p_range.Item(p_8_index)

var1 = InterpolateAll(CDbl(percent_methane), CDbl(pressure), CDbl(temp), 4, m_range, p_range, t_range, CDbl(m1), CDbl(m2), CDbl(t1), CDbl(t2), CDbl(t3), CDbl(t4), CDbl(p1), CInt(p_1_index), p2, CInt(p_2_index), p3, CInt(p_3_index), p4, CInt(p_4_index), p5, CInt(p_5_index), p6, CInt(p_6_index), p7, CInt(p_7_index), p8, CInt(p_8_index))
Range("P4") = var1

End Sub

【问题讨论】:

  • 可以添加完整的功能代码吗?
  • 请贴一个完整的代码sn-p,其中包含导致问题的关键部分,否则有点不清楚。谢谢和问候,
  • 你读过this post吗?顺便说一句,您得到的错误似乎与您发布的代码没有任何关系。您为什么不尝试仅测试您发布的代码,看看它是否出错。 AFAIK 它不会。
  • 请注意,如果 WorksheetFunction.Match() 找不到匹配项,则代码将产生运行时错误 - 您可能需要查看适当的错误捕获/处理来解决此问题。
  • 您似乎不愿意使用像ThisWorkbook.Sheets("Data").Range("A1") 这样的完全限定引用。将With ThisWorkbook.Sheets("Data")End With 一起使用,并在With ... End With 中为与Sheets("Data") 相关的所有内容添加前缀Set m_range = .Range("A:A")。然后你就可以随意使用m_range了。

标签: vba excel


【解决方案1】:

一个常见的错误是在With ... End With 块中忽略了从属所有 适当的.Range.Cells 引用。由于您使用.Cells 引用来构造您的.Range 引用,因此这变得非常重要。请查看此重写;我添加了一些 cmets,但大多数是简单的引用和重组。

'Never a good idea to use a reserved word like 'column' as a variable. I changed to 'colm'
Function InterpolateAll(methane As Double, pressure As Double, temp As Double, _
  colm As Long, m_range As Range, p_range As Range, t_range As Range, m1 As Double, _
  m2 As Double, t1 As Double, t2 As Double, t3 As Double, t4 As Double, p1 As Double, _
  p_1_index As Long, p2 As Double, p_2_index As Long, p3 As Double, p_3_index As Long, _
  p4 As Double, p_4_index As Long, p5 As Double, p_5_index As Long, p6 As Double, _
  p_6_index As Long, p7 As Double, p_7_index As Long, p8 As Double, p_8_index As Long) As Double

    Dim v1 As Double, v2 As Double, v3 As Double, v4 As Double
    Dim v5 As Double, v6 As Double, v7 As Double, v8 As Double
    Dim vr1 As Double, vr2 As Double, vr3 As Double, vr4 As Double
    Dim vrr1 As Double, vrr2 As Double, vrrr As Double

    With Worksheets("Data")
        v1 = .Cells(p_1_index, colm)
        v2 = .Cells(p_2_index, colm)
        v3 = .Cells(p_3_index, colm)
        v4 = .Cells(p_4_index, colm)
        v5 = .Cells(p_5_index, colm)
        v6 = .Cells(p_6_index, colm)
        v7 = .Cells(p_7_index, colm)
        v8 = .Cells(p_8_index, colm)
    End With

    vr1 = Interpolate(pressure, p1, p2, v1, v2)
    vr2 = Interpolate(pressure, p3, p4, v3, v4)
    vr3 = Interpolate(pressure, p5, p6, v5, v6)
    vr4 = Interpolate(pressure, p7, p8, v7, v8)
    vrr1 = Interpolate(temp, t1, t2, vr1, vr2)
    vrr2 = Interpolate(temp, t3, t4, vr3, vr4)
    vrrr = Interpolate(methane, m1, m2, vrr1, vrr2)

    InterpolateAll = vrrr

End Function

Function Interpolate(a_desired As Double, a1 As Double, a2 As Double, p1 As Double, p2 As Double)

    Interpolate = (a_desired - a1) / (a2 - a1) * (p2 - p1) + p1

End Function

Private Sub ComButt()

    Dim m1 As Double, m2 As Double
    Dim t1 As Double, t2 As Double, t3 As Double, t4 As Double
    Dim p1 As Double, p2 As Double, p3 As Double, p4 As Double
    Dim p5 As Double, p6 As Double, p7 As Double, p8 As Double
    Dim m_range As Range, p_range As Range, t_range As Range
    Dim m_start As Range, p_start As Range, t_start As Range
    Dim m_range_1_top As Long, m_range_1_bottom As Long, m_range_2_top As Long, m_range_2_bottom As Long
    Dim t_range_1_top As Long, t_range_1_bottom As Long, t_range_2_top As Long, t_range_2_bottom As Long
    Dim t_range_3_top As Long, t_range_3_bottom As Long, t_range_4_top As Long, t_range_4_bottom As Long
    Dim p_1_index As Long, p_2_index As Long, p_3_index As Long, p_4_index As Long
    Dim p_5_index As Long, p_6_index As Long, p_7_index As Long, p_8_index As Long
    Dim pressure As Double, temp As Double, percent_methane As Double
    Dim var1 As Double

    With Worksheets("Data")
        pressure = .Range("S2").Value
        temp = .Range("R2").Value
        percent_methane = .Range("Q2").Value

        'this sets start_range as a value, not the A1 cell as a range. Maybe set start_range = .Range("A1")
        'in any event, it doesn't appear to be used after this so commented out
        'start_range = .Range("A1")
        'set start_range = .Range("A1")

        Set m_range = .Range("A:A")
        Set t_range = .Range("B:B")
        Set p_range = .Range("C:C")
        Set m_start = .Range("A1")
        Set t_start = .Range("B1")
        Set p_start = .Range("C1")

        m1 = m_range.Item(WorksheetFunction.Match(percent_methane, m_range))
        m_range_1_top = WorksheetFunction.Match(percent_methane, m_range)
        m_range_1_bottom = WorksheetFunction.Match(m1, m_range, 0)

        m2 = m_range.Item(m_range_1_top + 1)
        ' again, are _top and _bottom transposed here?
        m_range_2_top = WorksheetFunction.Match(m2, m_range)
        m_range_2_bottom = m_range_1_top + 1

        'ALL of the range and cell references need to be referenced to the With ... End With
        t1 = t_range.Item(WorksheetFunction.Match(temp, .Range(.Cells(m_range_1_bottom, 2), .Cells(m_range_1_top, 2))) + m_range_1_bottom - 1)
        t_range_1_top = WorksheetFunction.Match(temp, .Range(.Cells(m_range_1_bottom, 2), .Cells(m_range_1_top, 2))) + m_range_1_bottom - 1
        t_range_1_bottom = WorksheetFunction.Match(t_range.Item(t_range_1_top), .Range(.Cells(m_range_1_bottom, 2), .Cells(m_range_1_top, 2)), 0) + m_range_1_bottom - 1

        t2 = t_range.Item(t_range_1_top + 1)
        t_range_2_bottom = t_range_1_top + 1
        t_range_2_top = WorksheetFunction.Match(t2, .Range(.Cells(m_range_1_bottom, 2), .Cells(m_range_1_top, 2))) + m_range_1_bottom - 1

        t_range_3_top = WorksheetFunction.Match(temp, .Range(.Cells(m_range_2_bottom, 2), .Cells(m_range_2_top, 2))) + m_range_2_bottom - 1
        t_range_3_bottom = WorksheetFunction.Match(t_range.Item(t_range_3_top), .Range(.Cells(m_range_2_bottom, 2), .Cells(m_range_2_top, 2)), 0) + m_range_2_bottom - 1
        t3 = t_range.Item(t_range_3_bottom)

        t4 = t_range.Item(t_range_3_top + 1)
        t_range_4_bottom = t_range_3_top + 1
        t_range_4_top = WorksheetFunction.Match(t4, .Range(.Cells(m_range_2_bottom, 2), .Cells(m_range_2_top, 2))) + m_range_2_bottom - 1

        p_1_index = WorksheetFunction.Match(pressure, .Range(.Cells(t_range_1_bottom, 3), .Cells(t_range_1_top, 3))) + t_range_1_bottom - 1
        p1 = p_range.Item(p_1_index)

        p_2_index = p_1_index + 1
        p2 = p_range.Item(p_2_index)

        p_3_index = WorksheetFunction.Match(pressure, .Range(.Cells(t_range_2_bottom, 3), .Cells(t_range_2_top, 3))) + t_range_2_bottom - 1
        p3 = p_range.Item(p_3_index)

        p_4_index = p_3_index + 1
        p4 = p_range.Item(p_4_index)

        p_5_index = WorksheetFunction.Match(pressure, .Range(.Cells(t_range_3_bottom, 3), .Cells(t_range_3_top, 3))) + t_range_3_bottom - 1
        p5 = p_range.Item(p_5_index)

        p_6_index = p_5_index + 1
        p6 = p_range.Item(p_6_index)

        p_7_index = WorksheetFunction.Match(pressure, .Range(.Cells(t_range_4_bottom, 3), .Cells(t_range_4_top, 3))) + t_range_4_bottom - 1
        p7 = p_range.Item(p_7_index)

        p_8_index = p_7_index + 1
        p8 = p_range.Item(p_8_index)

        var1 = InterpolateAll(CDbl(percent_methane), CDbl(pressure), CDbl(temp), 4, m_range, p_range, t_range, CDbl(m1), CDbl(m2), CDbl(t1), CDbl(t2), CDbl(t3), CDbl(t4), CDbl(p1), CInt(p_1_index), p2, CInt(p_2_index), p3, CInt(p_3_index), p4, CInt(p_4_index), p5, CInt(p_5_index), p6, CInt(p_6_index), p7, CInt(p_7_index), p8, CInt(p_8_index))
        .Range("P4") = var1
    End With

    Set m_range = Nothing
    Set t_range = Nothing
    Set p_range = Nothing
    Set m_start = Nothing
    Set t_start = Nothing
    Set p_start = Nothing
End Sub

【讨论】:

  • 好的,所以我尝试的第一件事就是用完全限定的版本替换所有range( 实例:ThisWorkbook.Sheets("Data").Range("A1")] 在 word 中使用 [ctrl+H]。上面的修订使一切正常工作(谢谢!!)所有Cells() 对象都没有正确限定的问题是什么?顺便说一句,您知道为什么 worksheet("data").Activate 技巧不起作用吗?
  • @bluefabric - 是的,如果这已经克服了困难,那么它正在尝试定义一个Range,归结为<undefined sheet>.Cells(upper boundary)<undefined sheet>.Cells(lower boundary)。在 XL 看来,可以重新定义 ActiveSheet 的细微差别是多种多样的。可以说,它绝不是提交单元格或范围引用的亲子关系的可靠方法(并且完全没有必要/没有生产力)。此外,只要您记得在前面加上句号(例如句号或 .),包裹在 With ... End With 块中的所有内容看起来都更酷
【解决方案2】:

跳过激活您的工作表,并通过使用工作表的完整地址来声明值。

With ThisWorkbook.Sheets("Data")

    v1 = .Cells(p_1_index, column)
    v2 = .Cells(p_2_index, column)
    v3 = .Cells(p_3_index, column)
    v4 = .Cells(p_4_index, column)
    v5 = .Cells(p_5_index, column)
    v6 = .Cells(p_6_index, column)
    v7 = .Cells(p_7_index, column)
    v8 = .Cells(p_8_index, column)

    Set m_range = .Range("A:A")
    Set t_range = .Range("B:B")
    Set p_range = .Range("C:C")
    Set m_start = .Range("A1")
    Set t_start = .Range("B1")
    Set p_start = .Range("C1")

End With

运行调试器并在 WorksheetFunctions 开始发生的位置放置一个断点。然后逐步浏览它们,观察本地窗口以查看更改。如果仍然存在问题,您将看到问题所在。

【讨论】:

  • 在这样的分配块中,With ... End With 可能会更好。
  • 同意并修改。
  • 好吧-我试过了。子是错误总是存在的地方。错误所在的行位于m1 = m_range.Item(WorksheetFunction.Match(percent_methane, m_range))。不过,当时 percent_methane 是 5.5,范围应该包含 5 到 20 之间的值。我不太确定为什么会出现错误。 (另外,我以前从未听说过/使用过本地窗口,但从现在开始!很棒的资源)
  • 是否可能没有匹配项
  • @bluefabric - 1. m_range 中的值是否按升序排列?除非它们按升序排列,否则您不能将 MATCH 用于近似匹配。 2. percent_methane 实际上是 5.5 还是 0.055?如果它是 0.055 并且 m_range 从 5 开始,您将收到 #N/A 错误。
猜你喜欢
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多