2015-05-01 44 views
2

我在嘗試構建一個腳本,該腳本可提取列(用戶定義的)的前6個字符,並插入一個新列並粘貼這些結果,或者只是將這些結果通過已存在的結果列(用戶的選擇),但我不斷收到一個對象定義錯誤(我用星號標記了代碼中的行)。Excel VBA腳本中的對象定義錯誤

誰能告訴我我做錯了什麼?這裏是我的代碼

Sub AAC_Extract() 
    Dim rng As Range, col As Range, arr 
    Dim sht As Worksheet, shet As Worksheet 

    On Error Resume Next 
    Set rng = Application.InputBox(_ 
       Prompt:="Please select the column that contains the Standard Document Number. " & vbNewLine & _ 
         " (e.g. Column A or Column B)", _ 
       Title:="Select Document Number Range", Type:=8) 
    On Error GoTo 0 
    hdr = MsgBox("Does your selection contain a header?", vbYesNo + vbQuestion, "Header Option") 

    Set dest = Application.InputBox(_ 
       Prompt:="Please select the column that you would the AAC to be placed in. " & vbNewLine & _ 
         " (e.g. Column B or Column C)", _ 
       Title:="Select Destination Range", Type:=8) 

    If dest Is Nothing Then Exit Sub 
    Set sht = dest.Worksheet 
    Set shet = rng.Worksheet 
    'If dest = rng Then 
    ' MsgBox "Your Destination Range can not be the same as your Reference Range. Please choose a valid Destination Range", vbExclamation 
    ' Exit Sub 
    'End If 


    On Error GoTo 0 
    yn = MsgBox("Do you want to insert a new column here?" & vbNewLine & _ 
         "(Choosing 'No' will replace the current cells in your selected range." & vbNewLine & "All data in this range will be permanently deleted.)", vbYesNo + vbQuestion, "Destination Range Options") 


    LastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row 

    Application.ScreenUpdating = False 
    If hdr = vbYes And yn = vbYes Then 
     dest.Select 
     With Selection 
     .EntireColumn.Insert 
     End With 
     Set col = sht.Range(sht.Cells(2, dest.Column), _ 
         sht.Cells(sht.Rows.Count, dest.Column).End(xlUp)) 
     Set cols = shet.Range(shet.Cells(2, rng.Column), _ 
         shet.Cells(shet.Rows.Count, rng.Column).End(xlUp)) 
     'Columns = cols.Column 
     'dest.EntireColumn.Insert 
     'col = dest.Column 
     'cols = rng.Column 
     'For i = 1 To LastRow 
     'Cells(i, col).Value = Left(Cells(i, cols), 6) 
     'Next i 
     'For Each c In col.Cells.Offset(0, -1) 'Offset due to the fact that dest moved when a column was inserted 
     ' i = c.Row 
     ' c.Value = Left(cols.Cells(i - 1), 6) 'Honestly, I'm not sure why I have to subtract 1 from i....i should be the same row as c 
     'Next c 
     With col 
     .Value2 = cols.Value2 
     .TextToColumns Destination:=.Cells, DataType:=xlFixedWidth, _ 
     FieldInfo:=Array(Array(0, 1), Array(6, 9)) 
     End With 
    End If 

End Sub 
+1

我沒有看到任何''哪條線給你的麻煩? – Brad

+0

@布拉德對不起,關於這一點。我編輯腳本以顯示星號。除了我注意到的方式之外,我無法想象如何處理它。我想如果我能解決這部分問題,我可以爲其他3個布爾代碼編寫代碼。 –

回答

1

很可能sht爲空。

Dim sht as Worksheet但從來沒有Set它到任何東西。您的錯誤行是使用sht的第一行,因此恰好是錯誤引起您注意的地方。

我會瘦你想要將它設置到與dest範圍相關聯的工作表。

set sht = dest.Worksheet 

cols打交道時,你必須要小心不要重複使用變量,但(你可以考慮重命名這些更明確的瞭解他們在做什麼,但是那是另一回事)。按照您設置destrng的方式,它們不能保證來自相同的表格,這會在設置colcols時產生問題。如果您嘗試使用不同工作表上的單元格組合範圍,則會發生異常。

+0

感謝您的信息。說實話,我並不完全理解這一切,但我會一直重複它,直到我做到。 我添加了set sht = dest.worksheet,它讓我超越了我被困住的地步。 現在它給我一個錯誤的最後一部分: 關於C在col.Cells c.Value =左(細胞(我,cols.column),6) 下一個C 你有什麼想法爲什麼我不能使用這種語法? 我將cols設置爲一個範圍,並選擇我和範圍列的列號,對吧?或者,也許我誤解了這一點。 –

+0

語法看起來不錯...您是否使用過調試器來查看'cols.column'的值?它指向什麼表單?使用本地和觀察窗口瞭解變量的值。請記住,如果在沒有引用表的情況下使用'Cells'(例如:'Sheets(1).Cells(i,cols.Column)'將在您的Activesheet中引用一個範圍。使用Fully Qualified每個範圍對象('Range'或'Cells')都是一個表單的子對象,你希望儘可能的明確表單是什麼表單,不要讓Excel爲你做決定 – Brad

+0

@flwr_pwr這裏有一個例子,當我說「你設置目標的方式和rng不能保證來自同一張表,這會在設置col和cols時導致問題」:'Set dest = Sheets(1).Range (Sheets(2).Cells(1,1),Sheets(1).Cells(2,3))''這會拋出異常「應用程序定義或對象定義的錯誤」。錯誤是有道理的,因爲你試圖從兩張不同的紙上的單元格構成一個連續的範圍,這樣做並不合乎邏輯 – Brad

0

在一個相關的說明,您可以非常快速地使用VBA的TextToColumn method,選擇的第一個字段作爲的寬度和丟棄任何其他領域獲得的六個最左側的字符轉換成整列。對於較長的值列,這應該在循環和拉出每個單元格的前六個字符方面產生顯着的差異。

在您提供的代碼的底部附近,您有以下循環。

For Each c In col.Cells 
     c.Value = Left(Cells(i, cols), 6) 
    Next c 

這似乎有COL定義爲前六個字符的從源列COLS 目的地。你循環遍歷每個單元格,並揭開前六個字符。

With col 
    .Value2 = cols.Value2 
    .TextToColumns Destination:=.Cells, DataType:=xlFixedWidth, _ 
     FieldInfo:=Array(Array(0, 1), Array(6, 9)) 
End With 

這從傳輸的cols值山坳剝掉任何過去的第六個字符一路經柱一次。

對於小於幾百個值的任何東西,我不知道是否會打擾重寫,但效率會增加需要處理的更多行值。

片段實施:

Sub AAC_Extract() 
    Dim rng As Range, col As Range, cols As Range, arr 
    Dim sht As Worksheet, shet As Worksheet, hdr As Long, yn As Long, LastRow As Long 
    Dim dest As Range 

    On Error Resume Next 
    Set rng = Application.InputBox(_ 
       Prompt:="Please select the column that contains the Standard Document Number. " & vbNewLine & _ 
         " (e.g. Column A or Column B)", _ 
       Title:="Select Document Number Range", Type:=8) 
    On Error GoTo 0 
    hdr = MsgBox("Does your selection contain a header?", vbYesNo + vbQuestion, "Header Option") 

    Set dest = Application.InputBox(_ 
       Prompt:="Please select the column that you would the AAC to be placed in. " & vbNewLine & _ 
         " (e.g. Column B or Column C)", _ 
       Title:="Select Destination Range", Type:=8) 

    If dest Is Nothing Then Exit Sub 
    Set sht = dest.Parent 
    Set shet = rng.Parent 

    On Error GoTo 0 
    yn = MsgBox("Do you want to insert a new column here?" & vbNewLine & _ 
       "(Choosing 'No' will replace the current cells in your selected range." & vbNewLine & _ 
       "All data in this range will be permanently deleted.)", vbYesNo + vbQuestion, "Destination Range Options") 


    LastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row 

    Application.ScreenUpdating = False 
    If yn = vbYes Then 
     dest.EntireColumn.Insert 
     Set dest = dest.Offset(0, -1) 
    End If 

    'I'm not sure about this because the next set starts in row 2 regardless 
    'If hdr = vbYes Then 
    ' Set dest = dest.Resize(dest.Rows.Count - 1, 1) 
    'End If 

    Set cols = shet.Range(shet.Cells(2, rng.Column), _ 
        shet.Cells(shet.Rows.Count, rng.Column).End(xlUp)) 
    Set col = sht.Cells(2, dest.Column).Resize(cols.Rows.Count, 1) 

    With col 
     .Value2 = cols.Value2 
     .TextToColumns Destination:=.Cells, DataType:=xlFixedWidth, _ 
      FieldInfo:=Array(Array(0, 1), Array(6, 9)) 
    End With 

End Sub 
+0

有趣。我試圖用你提供的方法;但是,在插入新列後,宏似乎沒有任何操作。你有什麼想法,爲什麼這可能是?我已更新Orignal Post中的代碼 –

+0

@flwr_pwr - 我已將代碼段添加到完全更新的代碼 – Jeeped

+0

中,效果非常好!非常感謝。非常有效。 如果你不介意的話,你能解釋一下這部分代碼: 「字段信息:=陣列(陣列(0,1),陣列(6,9))」 我只問,因爲我也有重新創建函數以拉動一個範圍的Mid(7,4),並且我喜歡使用相同的方法。 不幸的是,在通過你提供的語法字符串走完自己之後,它已經超出了我的頭。 –

相關問題