Excel 对象变量或块变量未随机设置(错误91)?

Excel 对象变量或块变量未随机设置(错误91)?,excel,vba,Excel,Vba,在这一行中弹出错误MOnachbar=FindMO_1.Offset(,off),它似乎几乎是随机发生的,我现在不是这样。 下面是我的代码。我在不同的范围内运行过几次,没有显示错误。我有大约5000行x&列需要循环,这里我只测试一行 Sub test_array() 'On Error Resume Next Application.ScreenUpdating = False Dim StartTime As Double Dim TimeTaken As D

在这一行中弹出错误
MOnachbar=FindMO_1.Offset(,off)
,它似乎几乎是随机发生的,我现在不是这样。 下面是我的代码。我在不同的范围内运行过几次,没有显示错误。我有大约5000行x&列需要循环,这里我只测试一行

Sub test_array()

    'On Error Resume Next
    Application.ScreenUpdating = False
    Dim StartTime As Double
    Dim TimeTaken As Double
    StartTime = Timer
    Dim wb As Workbook
    Set wb = ThisWorkbook
    Dim myRange As Range
    Dim sArr As Variant
    Dim MORange As Range
    Dim i As Long
    Dim j As Long
    Set MORange = wb.Worksheets("INPUT_WIND").Range("C2:BP2")
    Set myRange = wb.Worksheets("INPUT_WIND").Range("C950:BP950")
    Dim MO As String
    Dim off As Long
    Dim WeaMat As Range
    Set WeaMat = Workbooks.Open("C:\Users\Nikhil.srivatsa\Desktop\WeaMat").Worksheets(1).Range("A:A")
    Dim FindMO_1 As Range
    Dim MOnachbar As String
    Dim FindMO_2 As Range
    Dim MOcol As Long
    Dim Vneu As Long
    Dim desRange As Range 'destination range
    Dim ZeitStempel As String
    Dim FINORange As Range
    Dim FINDZeitStempel As Range
    Dim VFINO As Long
    Dim DateRange As Range
    Set DateRange = wb.Worksheets("INPUT_WIND").Range("B3:B950")
    Set FINORange = Workbooks.Open("C:\Users\Nikhil.srivatsa\Desktop\FINO raw-010119-310819").Worksheets(1).Range("A:A") 'öffnet FINO Datei und legt die SuchRange fest
    wb.Sheets.Add(after:=wb.Worksheets("INPUT_WIND")).Name = "Ersetzt" ' create new sheet
    Set desRange = wb.Worksheets("Ersetzt").Range("C950:BP950") 'Range im neuen Sheet

    DateRange.Copy wb.Worksheets("Ersetzt").Range("B3:B950") 'Dates und MOs rüberkopieren
    MORange.Copy wb.Worksheets("Ersetzt").Range("C2:BP2") 'Dates und MOs rüberkopieren
    sArr = myRange.Value 'Creates Array of All cells

    For i = LBound(sArr, 1) To UBound(sArr, 1) 'Rows

        For j = LBound(sArr, 2) To UBound(sArr, 2) 'Columns

            If sArr(i, j) <= 0 Or IsEmpty(sArr) = True Then

                off = 1

                Do While off <= 5
                    MO = MORange.Cells(1, j)
                    Debug.Print MO
                    Set FindMO_1 = WeaMat.Find(MO, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False) 'Lookup MO in WEA MAtrix
                    MOnachbar = FindMO_1.Offset(, off)
'                   Debug.Print MOnachbar
                    Set FindMO_2 = MORange.Find(MOnachbar, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False) 'lookup MONachbar in INPUT_WIND

                    MOcol = FindMO_2.Column - 2 'column Index für sArr
                    Vneu = sArr(i, MOcol)
                    Debug.Print Vneu

                    If Vneu > 0 And IsEmpty(Vneu) = False Then
                        sArr(i, j) = Vneu 'array value wurde ersetzt
                        desRange.Cells(i, j).AddComment.Text "Ersetzt durch" & " " & MOnachbar 'Kommentar
                        desRange.Cells(i, j).Font.Bold = True 'Bold font
                    Exit Do

                End If

                off = off + 1

                If off > 5 Then 'durch FINO daten ersetzen da mehr als 5 umliegende Anlagen entweder Blank oder 0 sind

                    ZeitStempel = myRange.Cells(i, j).Offset(, -j) 'als String / Text
'                   Debug.Print ZeitStempel

                    Set FINDZetiStempel = FINORange.Find(CDate(ZeitStempel), lookat:=xlWhole, MatchCase:=False, SearchFormat:=True) 'Cdate String ins Date umwandeln
                    If Not FINDZeitStempel Is Nothing Then

                        VFINO = FINDZeitStempel.Offset(, 1) 'FINO Wert
                        sArr(i, j) = VFINO
                        desRange.Cells(i, j).AddComment.Text "Ersetzt durch" & " " & "FINO" 'Kommentar
                        desRange.Cells(i, j).Font.Bold = True 'Bold font
                        Exit Do
                    Else
'                       Debug.Print "Zeitstempel nicht gefunden" & " " & ZeitStempel
                        ErrCnt = ErrCnt + 1
                        Exit Do
                    End If

                End If

              Loop

          End If

       Next j
    Next i

    desRange.Value = sArr

'   wb.Worksheets("Ersetzt").Range("C2").Select

    Workbooks("WeaMat").Close False 'close WeaMat without saving
    Workbooks("FINO raw-010119-310819").Close False 'close FINO datei ohne sie zu spiechern
    Application.Calculation = xlCalculationAutomatic
    TimeTaken = Round((Timer - StartTime) / 86400, 2)
    Debug.Print TimeTaken
    If ErrCnt <> 0 Then

        MsgBox "fertig in" & " " & TimeTaken & " " & "Sekunden" & vbCrLf & "einige FINO Zeitstempeln wurden nicht gefunden"
    Else

        MsgBox "fertig in" & " " & TimeTaken & " " & "Sekunden"
    End If
    Application.ScreenUpdating = True

End Sub
子测试_数组()
'出现错误时,请继续下一步
Application.ScreenUpdating=False
暗淡的开始时间是双倍的
双倍时间
开始时间=计时器
将wb设置为工作簿
设置wb=ThisWorkbook
将myRange变暗为Range
Dim-sArr作为变体
昏暗的莫兰格山脉
我想我会坚持多久
Dim j尽可能长
设置MORange=wb.工作表(“输入风”)范围(“C2:BP2”)
设置myRange=wb.工作表(“输入风”)范围(“C950:BP950”)
暗墨如弦
淡出
像射程一样暗的WeaMat
设置WeaMat=Workbooks.Open(“C:\Users\Nikhil.srivatsa\Desktop\WeaMat”)。工作表(1)。范围(“A:A”)
Dim FindMO_1作为范围
作为字符串的Dim MOnachbar
Dim FindMO_2作为范围
淡色莫科尔一样长
只要
将范围变暗为“目标范围”
将泽特佩尔变暗为弦
暗橙色作为射程
Dim FINDZeitStempel作为范围
将VFINO设置为长
日期范围变暗为范围
Set DateRange=wb.工作表(“输入风”)范围(“B3:B950”)
设置FINORange=Workbooks.Open(“C:\Users\Nikhil.srivatsa\Desktop\FINO raw-010119-310819”)。工作表(1)。范围(“A:A”)'ffnet FINO Datei and leg die SuchRange fest
wb.Sheets.Add(在:=wb.Worksheets(“输入风”)之后)。Name=“Ersetzt”创建新工作表
设置desRange=wb.工作表(“Ersetzt”).范围(“C950:BP950”)”范围im neuen表格
DateRange.复制wb.工作表(“Ersetzt”).Range(“B3:B950”)的日期和日期
MORange.复制wb.工作表(“Ersetzt”).范围(“C2:BP2”)“日期和MOs rüberkopieren
sArr=myRange.Value'创建所有单元格的数组
对于i=LBound(sArr,1)到UBound(sArr,1)'行
对于j=LBound(sArr,2)到UBound(sArr,2)'列
如果sArr(i,j)改变这一点:

Set FindMO_1 = WeaMat.Find(MO, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False) 'Lookup MO in WEA MAtrix
MOnachbar = FindMO_1.Offset(, off)
' etc...
为此:

Set FindMO_1 = WeaMat.Find(MO, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False) 'Lookup MO in WEA MAtrix
If FindMO_1 Is Nothing Then
    ' show an error message? break-out of a loop? exit the function?
    MsgBox "Find returned nothing"
    Exit Sub
Else
    MOnachbar = FindMO_1.Offset(, off)
    ' etc... 
End If

出于可读性和可维护性的主观考虑,我建议将变量声明移动到初始化或赋值的位置,如下所示:

(我最初认为VBA具有块级作用域,就像C和Java一样,但今天我了解到它只具有函数/子级作用域,因此我先前关于移动声明可以防止使用范围外变量的断言是错误的)


如果
Set FindMO_1=WeaMat.Find
失败,那么
FindMO_1
将是
Nothing
,并将在以后引起您的问题。@ExcelHero是的,我想避免几行代码,这几乎就像查找有时有效,有时无效一样。我在另一个脚本中使用了同一行代码,它发现“Mo”没有任何problems@Dai对不起,我不太明白你的意思,我对任何编程都是新手kind@Dai谢谢,我只是想避免那些代码,因为这个发现总是有效的,有趣。@neutronhammer但你的问题帖子表明
Find
并不总是有效:)在VBA中,过程中声明的变量具有过程级作用域,并在编译时初始化。。。在程序运行之前。你的“内联声明建议”是装饰性的,你的偏好,误导性的和错误的。@ExcelHero哇-那太可怕了:(我的错误!我以为VBA的变量有块级别的作用域。我现在就更正我的帖子。
Dim FindMO_1 As Range
Set FindMO_1 = WeaMat.Find(MO, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False) 'Lookup MO in WEA MAtrix
If FindMO_1 Is Nothing Then
    ' show an error message? break-out of a loop? exit the function?
    MsgBox "Find returned nothing"
    Exit Sub
Else
    MOnachbar = FindMO_1.Offset(, off)
    ' etc... 
End If