如何在excel vba中设置块变量

时间:2016-04-19 06:22:15

标签: excel vba excel-vba

我收到了run-time error: 91 "Object variable or with block variable not set

这是我的代码,我不是我错了什么

With Sheet1
lastrowcell = Range("B" & Rows.Count).End(xlUp).Row
pr_high = 14
For n = pr_high To lastrowcell

Max = WorksheetFunction.Max(Range(Cells(n - pr_high_1, 6), Cells(n, 6)))

If Max > 0 Then
    rowNum = .Columns(6).Find(What:=Max, after:=.Cells(n - period_high, 6), LookIn:=xlFormulas, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False).Row
    '>>>>At above line I'm getting an error.

    Range(Cells(n - pr_high_1, 8)).Formula = "=Count(" & Range(Cells(n - pr_high_1, 6), Cells(rowNum, 6)).Address(False, False) & ")"
End If

Next

提前致谢。

1 个答案:

答案 0 :(得分:2)

在OP的完整代码发布后

编辑

我想我在Function calculate_high_low中找到了两行不正确的行,即

1)"计数最大值"块

rowNum = .Columns(6).Find(What:=Max, after:=.Cells(n - period_high, 6), LookIn:=xlFormulas, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False).Row

应该是

rowNum = .Columns(6).Find(What:=Max, After:=.Cells(n - period_high, 6), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False).Row

因为您正在查看单元格公式而不是其内容,因此您无法捕捉到您所寻找的价值

2)" Count Minium low"块

rowNum2 = .Columns(6).Find(What:=mymin, After:=.Cells(n - period_high, 6), LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False).Row

应该是

rowNum2 = .Columns(6).Find(What:=Min, After:=.Cells(n - period_low, 6), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False).Row

因为您正在查看单元格公式而不是其内容,因此您无法捕捉到您所寻找的价值

此外,您使用period_high代替period_low

但是其他人(我更多地说)比那更好,你总是更好:

  • 在模块的最顶层使用Option Explicit语句

    它会迫使你做一些额外的工作并定义所有变量及其类型,但会使调试和代码维护变得更加容易。例如,它会弹出所有变量名称错误,例如pr_high vs pr_high_1和(可能)period_high vs period_high

  • 为您的范围使用完全限定的参考,直到工作表和工作簿 确保您指向正确工作簿的正确工作表,否则他们默认为活动工作表和工作簿

因此,您的Function calculate_high_low会针对以上 以上的内容进行重构:

Public Function calculate_high_low(com_tick_ask As String, rng As Variant)

Dim lastrowcell As Long, rowNum As Long, rowNum2 As Long
Dim pr_high As Long, period_high As Long, period_low As Long, pr_low As Long, pr_high_1 As Long, pr_low_1 As Long, n As Long
Dim Max As Double, Min As Double

Dim calcSht As Worksheet


    Range("A:A,E:E,F:F,H:H").Copy '<=it's referring to currently active sheet which, as it's currently called from sub "CommandButton1_Click" above, is the sheet with which the last opened ".csv" file shows
    Worksheets.Add

    Set calcSht = ActiveSheet 'it's the added new sheet

    With calcSht

        .Range("A1").PasteSpecial xlPasteValuesAndNumberFormats
        Application.CutCopyMode = False
        'Range("C1").Value = "Formula High"
        'Range("D1").Value = "Count High"
        'Range("E1").Value = "Formula Low"
        'Range("F1").Value = "Count Low"

        .Range("1:1").Font.FontStyle = "Bold Italic"

        lastrowcell = .Range("B1", .Range("B1").End(xlDown)).Count
        'lastrowcell = .Range("B1:B" & .Cells(.Rows.Count, 2).End(xlDown).Row).Count

        'count average of high and low
        .Range("F2:F" & lastrowcell).Formula = "=Average(" & .Range("B2:C2").Address(False, False) & ")"

        'long
        period_high = high_low.period_1.Text
        period_low = high_low.period_2.Text

        pr_high = period_high + 1
        pr_low = period_low + 1

        pr_high_1 = period_high - 1
        pr_low_1 = period_low - 1


        'Count Maximum High
        For n = pr_high To lastrowcell
            Max = WorksheetFunction.Max(Range(.Cells(n - pr_high_1, 6), .Cells(n, 6)))

            If Max > 0 Then
               rowNum = .Columns(6).Find(What:=Max, After:=.Cells(n - period_high, 6), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False).Row
            'rowNum = WorksheetFunction.Max(Range(Cells(n - period_high, 6), Cells(n, 6)))
               Range(.Cells(n - pr_high_1, 8), .Cells(lastrowcell, 8)).Formula = "=Count(" & Range(.Cells(n - pr_high_1, 6), .Cells(rowNum, 6)).Address(False, False) & ")"
            End If
        Next



        'Count Minium low
        For n = pr_low To lastrowcell
            Min = WorksheetFunction.Min(Range(.Cells(n - pr_low_1, 6), .Cells(n, 6)))

            If Min > 0 Then
'                rowNum2 = .Columns(6).Find(What:=mymin, After:=.Cells(n - period_high, 6), LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False).Row
                rowNum2 = .Columns(6).Find(What:=Min, After:=.Cells(n - period_low, 6), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False).Row
                'rowNum2 = WorksheetFunction.Min(Range(Cells(n - period_high, 6), Cells(n, 6)))
                Range(.Cells(n - pr_low_1, 10), .Cells(lastrowcell, 10)).Formula = "=Count(" & Range(.Cells(n - pr_low_1, 6), .Cells(rowNum2, 6)).Address(False, False) & ")"
            End If

        Next


        'Calculate Formula for High & Low

        'For high
        .Range("G2:G" & lastrowcell).Value = "=(" & period_high & "-" & .Range("H2").Address(False, False) & ")/" & period_high

        'For Low
        .Range("I2:I" & lastrowcell).Value = "=(" & period_low & "-" & .Range("J2").Address(False, False) & ")/" & period_low



    End With
    high_low.Hide

End Function

正如我所说,这应该只是你的起点,因为你发布的整个代码缺乏良好的编码模式,很可能在这一步之后就失败了,如果上面的内容完全解决了这个问题。

但是如果你遵循建议的模式,你应该更容易捕捉所有可能的问题,即使是那些逻辑问题,因为明确的代码可以让你专注于他必须开发的算法