2012-09-18 115 views
3

有人可以幫助我的代碼,我得到一個下標越界錯誤:VBA下標越界 - 錯誤9

enter image description here

了「創建表被突出後的行在調試器中爲黃色

'Validation of year 
If TextBox_Year.Value = Format(TextBox_Year.Value, "0000") Then 

'Creating Process 
'Creation of new sheet 
Workbooks.Add 
ActiveWorkbook.SaveAs FileName:= _ 
    "" & Workbooks("Temperature Charts Sheet Creator").Sheets("MENU").Cells(4, 12).Value & "Data Sheet - " & ComboBox_Month.Value & " " & TextBox_Year.Value & ".xls", FileFormat _ 
    :=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:= _ 
    False, CreateBackup:=False 

'Creating of the sheets 
Windows("Data Sheet - " & ComboBox_Month.Value & " " & TextBox_Year.Value & ".xls").Activate 

    Sheets("Sheet3").Select 
    Sheets("Sheet3").Name = "31 " & ComboBox_Month.Value 
    Sheets("Sheet2").Select 
    Sheets("Sheet2").Name = "30 " & ComboBox_Month.Value 
    Sheets("Sheet1").Select 
    Sheets("Sheet1").Name = "29 " & ComboBox_Month.Value 

For i = 28 To 1 Step -1 

    Sheets.Add 
    ActiveSheet.Name = i & " " & ComboBox_Month.Value 

Next 

回答

1

當您嘗試引用無效集合的索引時,發生下標超出範圍錯誤。

很可能,Windows中的索引實際上並不包含.xls。該窗口的索引應與Excel的標題欄中顯示的工作簿的名稱相同。

作爲一個猜測,我會嘗試使用此:

Windows("Data Sheet - " & ComboBox_Month.Value & " " & TextBox_Year.Value).Activate 
13

提示如下簡化:從Workbooks.Add,而不是下標Windows()後捕獲返回值,如下所示:

Set wkb = Workbooks.Add 
wkb.SaveAs ... 

wkb.Activate ' instead of Windows(expression).Activate 


一般理念建議:

避免使用Excel的內置插件:ActiveWorkbook,ActiveSheet和Selection:捕獲返回值,並優先使用限定表達式。

僅在最外側的宏(子)中使用內置插入一次,並在宏開始時捕獲,例如,

Set wkb = ActiveWorkbook 
Set wks = ActiveSheet 
Set sel = Selection 

在和宏內不要依賴這些內置的名字,而不是捕捉返回值,例如

Set wkb = Workbooks.Add 'instead of Workbooks.Add without return value capture 
wkb.Activate 'instead of Activeworkbook.Activate 

此外,請嘗試使用合格的表達式,例如,

wkb.Sheets("Sheet3").Name = "foo" ' instead of Sheets("Sheet3").Name = "foo" 

Set newWks = wkb.Sheets.Add 
newWks.Name = "bar" 'instead of ActiveSheet.Name = "bar" 

使用合格的表達式,例如

newWks.Name = "bar" 'instead of `xyz.Select` followed by Selection.Name = "bar" 

這些方法將更好地工作在一般情況下,給予較少混亂的結果,重構(例如走動內和方法之間的代碼行)時會更加健壯,並且將跨版本的Excel工作得更好。例如,在從一個Excel版本到另一個版本的宏執行過程中,選擇會有所不同。

另請注意,使用更多限定表達式時,您可能會發現幾乎不需要.Activate。 (這可能意味着對於用戶來說,屏幕將閃爍較少)。因此,整行Windows(expression).Activate可以簡單地被消除,而不是被wkb.Activate所取代。

(另請注意:我認爲您顯示的.Select語句不起作用,可以省略。)

(我認爲Excel的宏錄製負責推廣使用ActiveSheet,ActiveWorkbook,選擇這種編程更脆弱的風格,選擇了這麼多,這種風格留下了很多需要改進的地方)

-2
Option Explicit 

Private Sub CommandButton1_Click() 
Dim mode As String 
Dim RecordId As Integer 
Dim Resultid As Integer 
Dim sourcewb As Workbook 
Dim targetwb As Workbook 
Dim SourceRowCount As Long 
Dim TargetRowCount As Long 
Dim SrceFile As String 
Dim TrgtFile As String 
Dim TitleId As Integer 
Dim TestPassCount As Integer 
Dim TestFailCount As Integer 
Dim myWorkbook1 As Workbook 
Dim myWorkbook2 As Workbook 


TitleId = 4 
Resultid = 0 

Dim FileName1, FileName2 As String 
Dim Difference As Long 



'TestPassCount = 0 
'TestFailCount = 0 

'Retrieve number of records in the TestData SpreadSheet 
Dim TestDataRowCount As Integer 
TestDataRowCount = Worksheets("TestData").UsedRange.Rows.Count 

If (TestDataRowCount <= 2) Then 
    MsgBox "No records to validate.Please provide test data in Test Data SpreadSheet" 
Else 
    For RecordId = 3 To TestDataRowCount 
    RefreshResultSheet 

    'Source File row count 
    SrceFile = Worksheets("TestData").Range("D" & RecordId).Value 
    Set sourcewb = Workbooks.Open(SrceFile) 
    With sourcewb.Worksheets(1) 
     SourceRowCount = .Cells(.Rows.Count, "A").End(xlUp).row 
     sourcewb.Close 
    End With 

    'Target File row count 
    TrgtFile = Worksheets("TestData").Range("E" & RecordId).Value 
    Set targetwb = Workbooks.Open(TrgtFile) 
    With targetwb.Worksheets(1) 
     TargetRowCount = .Cells(.Rows.Count, "A").End(xlUp).row 
     targetwb.Close 
    End With 

    ' Set Row Count Result Test data value 
    TitleId = TitleId + 3 
    Worksheets("Result").Range("A" & TitleId).Value = Worksheets("TestData").Range("A" & RecordId).Value 

    'Compare Source and Target Row count 
    Resultid = TitleId + 1 
    Worksheets("Result").Range("A" & Resultid).Value = "Source and Target record Count" 
    If (SourceRowCount = TargetRowCount) Then 
     Worksheets("Result").Range("B" & Resultid).Value = "Passed" 
     Worksheets("Result").Range("C" & Resultid).Value = "Source Row Count: " & SourceRowCount & " & " & " Target Row Count: " & TargetRowCount 
     TestPassCount = TestPassCount + 1 
    Else 
     Worksheets("Result").Range("B" & Resultid).Value = "Failed" 
     Worksheets("Result").Range("C" & Resultid).Value = "Source Row Count: " & SourceRowCount & " & " & " Target Row Count: " & TargetRowCount 
     TestFailCount = TestFailCount + 1 
    End If 


    'For comparison of two files 

    FileName1 = Worksheets("TestData").Range("D" & RecordId).Value 
    FileName2 = Worksheets("TestData").Range("E" & RecordId).Value 

    Set myWorkbook1 = Workbooks.Open(FileName1) 
    Set myWorkbook2 = Workbooks.Open(FileName2) 

    Difference = Compare2WorkSheets(myWorkbook1.Worksheets("Sheet1"), myWorkbook2.Worksheets("Sheet1")) 
    myWorkbook1.Close 
    myWorkbook2.Close 


    'MsgBox Difference 

    'Set Result of data validation in result sheet 
    Resultid = Resultid + 1 

    Worksheets("Result").Activate 
    Worksheets("Result").Range("A" & Resultid).Value = "Data validation of source and target File" 

    If Difference > 0 Then 
     Worksheets("Result").Range("B" & Resultid).Value = "Failed" 
     Worksheets("Result").Range("C" & Resultid).Value = Difference & " cells contains different data!" 
     TestFailCount = TestFailCount + 1 
    Else 
     Worksheets("Result").Range("B" & Resultid).Value = "Passed" 
     Worksheets("Result").Range("C" & Resultid).Value = Difference & " cells contains different data!" 
     TestPassCount = TestPassCount + 1 
    End If 


    Next RecordId 
End If 

UpdateTestExecData TestPassCount, TestFailCount 
End Sub 

Sub RefreshResultSheet() 
    Worksheets("Result").Activate 
    Worksheets("Result").Range("B1:B4").Select 
    Selection.ClearContents 
    Worksheets("Result").Range("D1:D4").Select 
    Selection.ClearContents 
    Worksheets("Result").Range("B1").Value = Worksheets("Instructions").Range("D3").Value 
    Worksheets("Result").Range("B2").Value = Worksheets("Instructions").Range("D4").Value 
    Worksheets("Result").Range("B3").Value = Worksheets("Instructions").Range("D6").Value 
    Worksheets("Result").Range("B4").Value = Worksheets("Instructions").Range("D5").Value 
End Sub 

Sub UpdateTestExecData(TestPassCount As Integer, TestFailCount As Integer) 
    Worksheets("Result").Range("D1").Value = TestPassCount + TestFailCount 
    Worksheets("Result").Range("D2").Value = TestPassCount 
    Worksheets("Result").Range("D3").Value = TestFailCount 
    Worksheets("Result").Range("D4").Value = ((TestPassCount/(TestPassCount + TestFailCount))) 
End Sub 
+1

儘管此代碼片段可能會解決問題,但[包括解釋](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)確實有助於提高帖子的質量。請記住,您將來會爲讀者回答問題,而這些人可能不知道您的代碼建議的原因。 – zondo