2017-06-29 155 views
1

我確定這裏有一個明顯的答案,但我被卡住了。這部分特別是拋出424:Object Required。對我來說,非常奇怪的部分是,它確實成功將0追加到列上,但隨後停止,並且不會繼續。追加到VBA中的單元格值

If cellLen < 9 Then 
     Set C.Value = 0 & C.Value 
End If 

爲了清楚起見,下面的代碼的其餘部分在下面。如果現在還不清楚,這是預期的碼流:

  1. 抓鬥命名字段
  2. 複製這些列到一個新的工作表
  3. 重命名它們,並刪除原片
  4. 創建一些新的薄板。用不同的腳本中使用
  5. 搜索特定列
  6. 丟失的前導0將其添加回(這是部分休息時間)
  7. 刪除行,其中特定列的單元格的值是0
  8. 拉那清理的列了一個新的文件,並將其保存

    Sub Cleanup_Mapwise_Import() 
    
    Dim targetCols As Variant 
    Dim replColNames As Variant 
    Dim index As Integer 
    Dim found As Range 
    Dim counter As Integer 
    Dim headerIndex As Integer 
    Dim question As Integer 
    Dim rowCount As Variant 
    Dim colNum As Variant 
    Dim colLetter As Variant 
    Dim C As Range 
    Dim cellLen As Integer 
    
    
    ' Add or remove fields to be copied here 
    
    targetCols = Array("gs_account_number", "gs_meter_number", "gs_amr_identification", _ 
            "gs_amr_phase", "gs_city", "Name", "Phase", _ 
            "gs_rate_schedule", "gs_service_address", _ 
            "gs_service_map_location", "gs_service_number") 
    
    ' Put the same fields from above in the desired order here, with the desired name 
    
    replColNames = Array("Acct #", "Meter #", "AMR ID", "AMR Phase", "City", _ 
            "Name", "Phase", "Rate", "Address", "Srv Map Loc", "Srv Num") 
    
    counter = 1 
    ActiveSheet.Range("A1").Select 
    
    ' This counts the number of columns in the source array and sets the index to that value 
    For index = LBound(targetCols) To UBound(targetCols) 
    
        Set found = Rows("1:1").Find(targetCols(index), LookIn:=xlValues, LookAt:=xlWhole, _ 
               SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False) 
    
    ' This is basically an insertion sort, and ends up with the columns in A:K 
    
        If Not found Is Nothing Then 
         If found.Column <> counter Then 
          found.EntireColumn.Cut 
          Columns(counter).Insert shift:=xlToRight 
          Application.CutCopyMode = False 
         End If 
         counter = counter + 1 
        End If 
    
    Next index 
    
    ' There is a more dynamic way of doing this, using index 
    ' As it is, replace A:K with the range of actual data 
    ' PROTIP: targetCols is 1-indexed, and has 11 entries --> 
    ' A:K encompasses that entire array --> 
    ' Add/subtract 1 for each entry you add/remove 
    
    Range("A:K").Cut 
    Set TargetSheet = Sheets.Add(After:=Sheets(Sheets.Count)) 
    TargetSheet.Name = "Contributors" 
    Range("A:K").Insert 
    question = MsgBox("Do you want to delete the original sheet?", vbYesNo + vbQuestion, "Delete Sheet") 
    If question = vbYes Then 
        Sheets(1).Activate 
        Sheets(1).Delete 
    Else 
        End If 
    Sheets.Add.Name = "Data" 
    Sheets("Contributors").Move After:=Sheets("Data") 
    Sheets.Add.Name = "Graph" 
    Sheets("Graph").Move After:=Sheets("Contributors") 
    Sheets("Data").Activate 
    Range("A1").Value = "Date/Time" 
    Range("B1").Value = "kW" 
    Range("C1").Value = "Amps" 
    
    ' Yes, counter is 0-indexed here, and 1-indexed previously 
    ' headerIndex does an absolute count of 0 To # targetCols, whereas index is relative 
    ' If you change these, there is a non-zero chance that the For will throw an error 
    
    counter = 0 
    Sheets("Contributors").Activate 
    ActiveSheet.Range("A1").Select 
    For headerIndex = 0 To (UBound(targetCols) - LBound(targetCols)) 
    
        ActiveCell.Value = replColNames(counter) 
        ' If you don't use a Range, it fits columns based on headers, which isn't large enough 
        ' A1:Z500 is a big enough sample to prevent that 
        ActiveCell.Range("A1:Z500").Columns.AutoFit 
        ActiveCell.Offset(0, 1).Select 
        counter = counter + 1 
    
    Next headerIndex 
    
    ' Find column number with meters numbers, then assign its corresponding letter value 
    colNum = Application.WorksheetFunction.Match("Meter #", Range("A1:ZZ1"), 0) 
    colLetter = (Split(Cells(, colNum).Address, "$")(1)) 
    rowCount = Range(colLetter & Rows.Count).End(xlUp).Row 
    
    'Range(colLetter & "2:" & colLetter & rowCount).Select 
    'Selection.SpecialCells(xlCellTypeBlanks).Select 
    'Selection.Delete Shift:=xlUp 
    
    ' Meter numbers are 9 digits, so if one is shorter, assume a trimmed leading 0 and append it 
    For Each C In Range(colLetter & "2:" & colLetter & rowCount).Cells 
        ' If cell type isn't set to text, the 0s will be non-visible, which while not an issue for the CSV, is confusing 
        ' Note that this does not persist, as CSVs have no way of saving Excel's formatting 
        C.NumberFormat = "@" 
        cellLen = Len(C.Value) 
        If C.Value = "0" Or cellLen = 0 Then 
         C.Delete shift:=xlUp 
        End If 
        If cellLen < 9 Then 
         Set C.Value = 0 & C.Value 
        End If 
    Next C 
    
    question = MsgBox("Do you want to create a CSV file with meter numbers for use with MDMS?", vbYesNo + vbQuestion, "MDMS File") 
    If question = vbYes Then 
        ' Call CopyMeters for use with MDMS 
        Sheets("Contributors").Activate 
        CopyMeters 
    Else 
        End If 
    End Sub 
    
    
    
    Sub CopyMeters() 
    Dim index As Integer 
    Dim fileSaveName As Variant 
    Dim rowCount As Variant 
    Dim colNum As Variant 
    Dim colLetter As Variant 
    Dim cellLen As Integer 
    
    
    colNum = Application.WorksheetFunction.Match("Meter #", Range("A1:ZZ1"), 0) 
    colLetter = (Split(Cells(, colNum).Address, "$")(1)) 
    rowCount = Range(colLetter & Rows.Count).End(xlUp).Row 
    
    MsgBox ("Filename will automatically be appended with ""Meter List""") 
    fileSaveName = Split(ActiveWorkbook.Name, ".") 
    fileSaveName = fileSaveName(LBound(fileSaveName)) & " Meter List" 
    
    'For Each C In Range(colLetter & "2:" & colLetter & rowCount) 
    ' C.NumberFormat = "@" 
    ' cellLen = Len(C) 
    ' If C.Value = "0" Or cellLen = 0 Then 
    '  C.Delete shift:=xlUp 
    ' End If 
    ' If cellLen < 9 And cellLen <> 0 Then 
    '  C.Value = "0" & C.Value 
    ' End If 
    'Next C 
    
    Range(colLetter & "1:" & colLetter & rowCount).EntireColumn.Copy 
    Set newBook = Workbooks.Add 
    newBook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteAll) 
    
    Selection.Replace What:="0", Replacement:="", LookAt:=xlWhole, _ 
        SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _ 
        ReplaceFormat:=False 
    
    Selection.Columns.AutoFit 
    newBook.SaveAs Filename:=fileSaveName, FileFormat:=xlCSV, CreateBackup:=False 
    
    End Sub 
    

回答

4

該錯誤消息告訴你,C是不是一個對象。因此,你不需要Set語句。將您的代碼更改爲:

If cellLen < 9 Then 
    C.Value = 0 & C.Value 
End If 
+0

好的......我向上帝發誓我之前曾嘗試過,並得到了相同的信息,因此我感到困惑。 無論如何謝謝你。 –

0

爲什麼不只是更改範圍內的numberformat?或者使用一個函數的值?函數會像

Public Function FormatValues(ByVal Input as String) as String 
    If Input <> vbNullString Then FormatValues = Format(Input, "000000000") 
End Function 

它會被稱爲像:

C.Value = FormatValues(C.Value) 

但是,如果你是在什麼樣的價值貌似嚴格的興趣,而不是儘可能多的價值是什麼是(因爲前導零將只保留字符串),你可以做這樣的事情:

Public Sub FixFormats() 
    ThisWorkbook.Sheets("SomeSheet").Columns("A").NumberFormat = "000000000") 
End Sub 

這將格式化Column A的Worksheet「SomeSheet」是的格式「0000000」,這意味着數字看起來像「000000001」,「000000002」等等,無論是否實際輸入了類似「2」的內容。

+0

我沒有改變範圍的格式,因爲B2包含「米#」,我不想格式化爲文本,出於某種原因。坦率地說,沒有關係,因爲它們被保存爲CSV格式,它們會去掉格式化 - 這隻會導致在保存前重新添加0,因此在用戶使用電子表格時看起來是正確的。 沒有使用函數,因爲我決不是一個完美的編碼器,特別是在VBA中,並且For Each正在工作。不過,我很欣賞解決這個問題的另一種方法。 –

相關問題